Le programme C suivant a une autre sortie si j'écrire quelque chose dans ma fonction principale et je ne comprends vraiment pas pourquoi ..non déterministe programme C trivial
Si nous commentons la déclaration myVariable, tout va bien et nous obtenir le résultat attendu (en appliquant 3 fois SHA256 à 0x12345678). Mais, si j'écris quelque chose dans la fonction principale, alors la sortie change et ne prend pas la valeur attendue.
Comment est-il possible que la déclaration d'une nouvelle variable affecte cela?
Le code (precompute.c):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
unsigned char* sha256_3(int* input) {
char *s = (char*)input;
unsigned char *d = SHA256(s, strlen(s), 0);
d = SHA256(d, strlen(d), 0);
d = SHA256(d, strlen(d), 0);
return d;
}
void print_hash(unsigned char* d) {
int i;
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
printf("%02x", d[i]);
putchar('\n');
}
int main(int argc, const char * argv[]) {
int A = 0x12345678;
unsigned char *B = sha256_3(&A);
print_hash(B);
// int myVariable = 3; // Uncomment this line and recompile to see the difference
return EXIT_SUCCESS;
}
Le Makefile:
CC=gcc
CFLAGS=-c
LDFLAGS=-lssl -lcrypto
SOURCES=precompute.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o [email protected] $(LDFLAGS)
.c .o:
$(CC) $(CFLAGS) $< -o [email protected]
clean:
rm -rf *o hello
La sortie attendue (déclaration de myVariable a commenté):
8f3d8f8c5eff23dc137762220cf24f140b7a1b804cc20442617 42fd73286c169
Une sortie inattendue (déclaration de myVariable décommentée):
663e9571f713f83b19c913938e2947c8fc0a7072d1fc442385857c456c43295b
Merci beaucoup!
vous n'avez jamais alloué d'espace. vous écrivez juste à la mémoire aléatoire (UB) –
aussi à peu près aucune de ces lignes de C n'a de sens. lire et écrire dans la même mémoire, en écrivant à plusieurs reprises aux pointeurs comme s'ils étaient des primitifs. Cela ne semble pas réductible, il suffit de recommencer. –
La longueur d'une chaîne C est déterminée par le caractère nul final, donc 'strlen (s)' est UB, car 's' ne fait que pointer vers un segment de mémoire – Dabo