-3

Why does this not return a segmentation fault 11?

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    char *test;
    test = (char*) (malloc(sizeof(char)*3));

    test = "foo";
    printf("%s\n", test);

    test = "foobar";
    printf("%s\n", test);

    return 0;
}

My outcome is

foo
foobar

I'm fairly new to C, but when I was compiling this using both gcc on mac and Windows Debugger on Windows 10, it doesn't crash like I expected.

My understanding is that by using (char*) (malloc(sizeof(char)*3)), I am creating a character array of length 3. Then, when I assign test to the string foobar I am writing to 6 array positions.

I'm left sitting here, staring at my apparently valid, runnable code scratching my head.

Setho246
  • 21
  • 4
  • You're leaking memory, not risking segmentation faults. Use `strcpy()` and friends to copy strings — use `strcmp()` to compare them. – Jonathan Leffler Aug 31 '18 at 02:44
  • Even if you had used `strcpy` or similar and thus actually written past the end of the buffer you allocated, you probably wouldn't have gotten a segfault. See https://stackoverflow.com/questions/43954449/why-does-the-buffer-overflow-in-this-code-behave-different-from-what-i-expect/43955348#43955348 for a great deal of explanation why writing past the end of a `malloc` block usually _doesn't_ produce a prompt crash. – zwol Aug 31 '18 at 03:14
  • Incidentally, it is hazardous to cast the result of `malloc` in C (it can hide bugs), and `sizeof(char)` is 1 _by definition_ so it's bad style to write it out like that. `char *test = malloc(3);` is proper. – zwol Aug 31 '18 at 03:15

3 Answers3

5
test = "foo";

Here you do not copy the string to the allocated memory, test no longer points to the allocated memory, instead it points to the string literal "foo". Same goes for "foobar". Also as pointed out in the comments the address of the allocated memory is lost and therefore it is a memory leak (since there is no way to retrieve the address of the memory).

If you want to copy a string to another destination you need to use strcpy or loop over every character.

If you write or read outside bounds of the allocated space you are invoking undefined behavior. That means that basicly everything can happen, also that it works.

Osiris
  • 2,783
  • 9
  • 17
  • 1
    +1, it is also worth to mention that `test = "foo";` causes memory leak, the pointer to the dynamically allocated memory is lost and can't be freed explicitly. – khachik Aug 31 '18 at 02:45
  • @khachik Yes i have added it. Thank you. – Osiris Aug 31 '18 at 02:47
2

Your program never writes to the location pointed to by the return from malloc(). All you've done with e.g. test = "foo"; is change what test points to, which by the way is a memory leak since you've then lost what malloc() returned.

To properly use the memory you allocated with malloc(), use strcpy(), snprintf(), etc.

Also, don't forget the null terminator in your C strings. To properly store e.g. "foobar" you need at least 7 bytes, not 6.

  • 1
    *"you've then lost what malloc() returned."* -- I know what you mean, but it is worth explaining that *"`test` no longer points to the block of memory returned by `malloc`, instead you've assigned the address of `"foo"` to `test` and your original reference to (pointer to) the block of memory returned by `malloc()` (originally stored in `test`) is no longer stored anywhere (it's lost) causing your program to leak memory"*. Like I said -- I know what you meant, but being a bit more verbose can help new programmers understand what *"lost"* means. – David C. Rankin Aug 31 '18 at 04:11
  • Good comments, David - I did think I put it in that context with my first sentence "...never writes to the location pointed to..." and with the second sentence "...change what `test` points to...", but maybe that wasn't enough. – GriffithLea Aug 31 '18 at 15:11
-1

First thing is that you waste the memory allocated by malloc unnecessorily by storing the address of foo into that. If you are going to point to string in code section then there is no need to allocate memory to the pointer.

When to allocate memory to pointer e.g. when you intended to scan 'n' number of bytes from keyboard in pointer.

      char *ptr,num_char;
      scanf("%d",&num_char);
      ptr =  (char *)malloc(num_char*sizeof(char)); 
      scanf("%s",ptr);
user694733
  • 15,208
  • 2
  • 42
  • 68
new_learner
  • 131
  • 10