3

My question is: what's the difference between those 2 lines:

int ptr[4046];
bzero(ptr, 4046);

int *ptr;
ptr = (int *)malloc(sizeof(int) * 4046);
bzero(ptr, 4046);

I ask this because when I want to print the ptr, the first one print some 0 and then garbage (random numbers) and the second (the malloc one) print only 0, like I would like to. I use printf to print it, like this:

int i = 0;
while (i++ < 4046)
  printf("%x", ptr[i]);

EDIT: Thanks to Everyone, Answer: the size is of a int is not 1 byte but 4 bytes. So the first 4046 byte is valid and after I print what's the computer can find on the stack.

  • bzero is a legacy routine: no idea what the implementation is. Try memset and see if you get the same result. – cup Aug 28 '18 at 03:10
  • 3
    @jenesaisquoi that is not true. In fact the exact opposite is true. Static linkage (globals, statics) is zero initialized; not automatics. – WhozCraig Aug 28 '18 at 03:11
  • 1
    Stop the impending deluge of answers to questions your not actually asking by clarifying your question (as well as stem the misinformation, of which there appears plenty). Is it your observation that `bzero` doesn't seem to be fully-zero'ing the stack based array, but seems to function correctly on the dynamic array, and you want to know why? You seem to know the difference between dynamic and automatic storage. So, is this about `bzero` apparently not working as you expect? – WhozCraig Aug 28 '18 at 03:17
  • @WhozCraig: You are right, but that still doesn't fit the description. Provided the compiler behaves as an abstract machine would, this code would produce a single garbage value at the end, not "random numbers". – AnT stands with Russia Aug 28 '18 at 03:24
  • @AnT The description is "the first one print some 0 and then garbage". It doesn't specifically say how many 0's and how much garbage. – dbush Aug 28 '18 at 03:28
  • @dbush: Formally you are right (ignoring the plural in "numbers"). But it is still quite a stretch. It is strange that 4047 zeros and a single (!) garbage value at the end is described as "some 0 and then random numbers". – AnT stands with Russia Aug 28 '18 at 03:29
  • I had ~1024 '0' and after some random numbers.. I didn't copy the code, I write a new for my question, I should copy/paste it.. Thank you everyone ! – MaxenceJdeD Aug 28 '18 at 04:04
  • Using 4048 is an unusual number. Either 2048 or 4096 would be very normal. – Jonathan Leffler Aug 28 '18 at 06:26

2 Answers2

4

There's no difference in how bzero works whether the memory is allocated on the stack or on the heap. The real problem is with how you're printing the contents:

int i = 0;
while (i++ < 4048)
  printf("%x", ptr[i]);

On the first iteration of the loop, the value of i (0) is compared against 4048. It is less, so the loop is entered, but not before i is incremented. Then the value of ptr[i], i.e. ptr[1] is printed. So you skip printing the first value.

Jumping ahead to the end, i is 4047 which is less than 4048 so the loop is entered, and again i is incremented before entering the loop body. Then the value of ptr[4048] is printed, however this value is past the end of the array / allocated memory, so reading it invokes undefined behavior. In this particular case, UB manifests as different garbage values being printed for each of the two cases.

You need to fix the loop to perform the increment inside the loop body:

int i = 0;
while (i < 4048)
  printf("%x", ptr[i++]);
dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    Or just use a for-loop as is commonly done. I just hope the OP didn't give up on this. – WhozCraig Aug 28 '18 at 03:23
  • Yes you are right, I go off by one. Thanks ! But the error where somewhere else. I use a `int *` and not a `char *` in my code. The size of a char is not the same than a int (1 and 4) – MaxenceJdeD Aug 28 '18 at 03:46
0

The first one allocates memory on the stack, the second one allocates on the heap

smac89
  • 39,374
  • 15
  • 132
  • 179