0
int strings(void){
  int NumStrings = 3;
  char **strings = (char**) malloc(sizeof(char*) * NumStrings);
  int i;
  char * element = "Trevor";
  for(i = 0; i < NumStrings; i++){
     strings[i] = ((char*) malloc(sizeof(char) * strlen(element)+1));
  }
  strings[0] = "abcdef";
  strings[1] = "lemons";
  strings[2] = "zoozoo13333";
  for(i = 0; i < NumStrings; i++){
    printf("%s\n", strings[i]);
  }
}

Why is this not causing a seg fault? I haven't allocated enough memory for "zoozoo13333", but it still prints fine, and doesn't throw any errors. Shouldn't there only be enough room in the array for a string that is 6 characters long?

  • 1
    Assigning a string literal doesn’t need any memory allocation. You’re actually leaking memory here. Also don’t cast the return value of `malloc` and `sizeof(char)` is always 1 – Sami Kuhmonen Oct 07 '17 at 06:12
  • Because you don't have a buffer overflow, but a memory leak: `strings[2] = "zoozoo13333";` will discard the handle to allocated memory and assign the string literal. – M Oehm Oct 07 '17 at 06:12

2 Answers2

1

You're not getting a buffer overflow because you're not writing into the buffer at all.

strings[2] = "zoozoo13333";

doesn't copy the string, it simply changes strings[2] to point to the memory of the string literal instead of the buffer you allocated with malloc(). As a result, you have a memory leak because you have allocated memory but nothing points to it any more.

To copy a string, you have to use strcpy(). You would get a buffer overflow if you did:

strcpy(strings[2], "zoozoo13333");

This causes undefined behavior because you write beyond the end of the buffer. It won't necessarily cause a segmentation fault. See Why don't I get a segmentation fault when I write beyond the end of an array?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I added the strcpy to the program, and you're right even though I allocated just enough memory for a string of 6 length, it still prints "zoozoo13333". So its up to me to know the size of strings I'm adding to the array? Is there any way to prevent a string that is less than the allocated space, from begin allowed to be added to the list? – Trevor Good Oct 07 '17 at 06:28
  • Try assigning the long string to `strings[0]` instead of `strings[2]`, I'll bet you notice something weird. – Barmar Oct 07 '17 at 06:29
  • Yes, C doesn't automatically detect writing out of bounds. Instead of allocating all the buffers with the same size, why don't you allocate each of them with the size of the string you're going to copy to it. You could also use the `strdup()` function, it does this automatically for you. – Barmar Oct 07 '17 at 06:31
  • Ya there I see the problem. Thanks, its adding the next element to the very end... Quite strange behavior. And thanks I'll look into that function. – Trevor Good Oct 07 '17 at 06:32
0

I haven't allocated enough memory for "zoozoo13333", but it still prints fine, and doesn't throw any errors.

You should realize that whenever you do something like "zoozoo13333", memory is already allocated for the bunch of characters (and a trailing \0 as well). But, this memory happens to be allocated in a region that you can't modify. In other words, you can't change this string itself. As memory is allocated (implicitly) and your string is valid, it prints fine.

Shouldn't there only be enough room in the array for a string that is 6 characters long?

Now, strings[i] is just a pointer to a char that's all. You are assigning to a pointer to a char correctly when you do this: strings[2] = "zoozoo13333";. There is no buffer overflow. As mentioned above, the space for the string has already been set aside somewhere else. What you are loosing is a handle to the allocated space that you got using malloc(). Thus, you can't free this space and you have a memory leak.

babon
  • 3,615
  • 2
  • 20
  • 20