0

I was reading this post and the OP says that he was worried that "that appending A's allocated memory will corrupt the heap ", so he instead allocated new memory, memcopy A, and memset.

i was wondering if that is the case. is it not possible to append without allocating new memory.

I made a lame attempt. and i got an error

int a[3] = {14, 2, 7};   // initialize array
int M = 2;
int size = sizeof a / sizeof a[0];    // size of array

// print contents of array 
for (int i=0;i<size;i++) {
    printf("%d\n", a[i]); 
}

// add (post pad) 2 zeros to existing array , a 
memset(a+M, 0, M * sizeof(int));


int size2 = sizeof a / sizeof a[0];
printf("%d\n", size2);

// print updated array 
for (int i=0;i<size2;i++) {
    printf("%d\n", a[i]); 
}


"*** stack smashing detected ***: terminated"
whoknowsmerida
  • 134
  • 2
  • 10
  • 2
    Arrays sizes are fixed. C doesn't have dynamic arrays. *Also*, C have no bounds checking, it's your job as the programmer to make sure the code doesn't go out of bounds of arrays and allocated memory. – Some programmer dude Aug 16 '22 at 10:03
  • 1
    `int a[3]` means that the `a` array can contain has exactly three elements, period. There is no way to make a C array bigger or smaller. – Jabberwocky Aug 16 '22 at 10:05
  • 2
    It's pointless to speculate about undefined behavior, but in your case you are "corrupting the stack", not the heap. – William Pursell Aug 16 '22 at 10:08

2 Answers2

2

In C there is no such thing as dynamic arrays. The size of the array must also be constant throughout the program and cannot change.

There is also no boundary checking so that is up to you to do as the programmer.

The array you created is a static array with space for 3 integers.

Your call to memset() is erroneous.

memset requires the following:

void *memset(void *s, int c, size_t n);

s = starting address of memory to be filled

c = value to be filled into memory

n = Number of bytes to be filled starting from s to be filled

Your code defines s as a[2], this will cause problems because memset() will try to access memory beyond what the allocated size of a is which can cause a buffer overflow bug.

Secondly it can cause a problem on the stack. Since the array a has a set size, when you try to write beyond this set size, you are accessing memory which does not belong to you and potentially over-writing important data in a stack frame that is not yours.

To put it simply the stack contains a unique value known as a "stack canary" which are placed between each stack frame. If this value is overwritten then the operating system knows the next stack frame was overwritten and a stack smashing event occured and an error is shown.

programmer
  • 462
  • 1
  • 6
0

C does not allow you to write to an array out-of-bounds, no matter where it is allocated. Doing so is undefined behavior and anything can happen.

// add (post pad) 2 zeros to existing array , a 
memset(a+M, 0, M * sizeof(int));

This code doesn't exactly do what the comment claims, because it starts by overwriting item a[2] with zero them continues to write out of bounds 1xsizeof(int) bytes from there. What happened in your specific case ("stack smashing") is likely that the code killed a so-called "stack canary" and so the stack corruption was detected. Which is a nice service by the compiler, but by no means guaranteed to happen. You might as well corrupt other variables or cause the program to crash.

Lundin
  • 195,001
  • 40
  • 254
  • 396