-3

I was testing a c program in order to see what happens in a loop if inside a string allocated with malloc i replace \0 with any other character. What I thought it gave me as output is either segmentation fault or access to another area of ​​memory since malloc returns a memory area of ​​a specific number of bytes. However, I found out some strange behavior with malloc. Here is my code:

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

void foo(char *s)
{
    int i = 0;
    while(s[i])
        i++;
    s[i++] = '5';
    return ;
}

int main(int argc, char **argv)
{
    char *s = malloc(4);
    printf("%p\t%s\n", s, s);

    strcpy(s, "test");
    printf("%p\t%s\n", s, s);

    foo(s);
    printf("%p\t%s\n", s, s);

    foo(s);
    printf("%p\t%s\n", s, s);

    return 0;
}

idk even if i allocate for 4 bytes in the foo function the character are added correctly in the second call of foo(). this is the output:

0x131606960
0x131606960     test
0x131606960     test5
0x131606960     test55

But then i changed the s declaration with malloc(1) and still produce the same output, strcpy also works fine (Why this happen? shouldn't it give segmentation fault? Maybe the OS operates under the hood in this case?). The strange behavior occurs when I replace with malloc(0), that, according to the specification malloc(0) have to return a NULL pointer but with the possibility to pass pointer to the free() function. Thus, it's basically the same thing as doing

char *s = NULL;

instead produce this output:

0x146704080
0x146704080     test
0x146704080     test5
0x146704080     test55

Anyone know why this happens?

pm100
  • 48,078
  • 23
  • 82
  • 145
username
  • 15
  • 4
  • When you use more space than is allocated to you, it is ***Undefined Behavior***. A Seg Fault is one possible outcome, so is Nasal Demons, and so is seemingly-correct behavior. There are NO GUARANTEES when you use invalid memory. – abelenky Nov 26 '22 at 15:51
  • try out https://linux.die.net/man/3/efence – pm100 Nov 26 '22 at 23:58
  • or try valgrind, – pm100 Nov 26 '22 at 23:59
  • https://stackoverflow.com/questions/2022335/whats-the-point-of-malloc0 https://stackoverflow.com/questions/2132273/what-does-malloc0-return https://stackoverflow.com/questions/10684595/behaviour-of-malloc0 https://stackoverflow.com/questions/33346622/why-does-malloc-work-with-zero-size https://stackoverflow.com/questions/1073157/zero-size-malloc – KamilCuk Nov 27 '22 at 00:01

1 Answers1

2

This malloc reference might be useful to read:

If size is zero, the behavior of malloc is implementation-defined. For example, a null pointer may be returned. Alternatively, a non-null pointer may be returned; but such a pointer should not be dereferenced, and should be passed to free to avoid memory leaks.

So malloc may return NULL, or it may not. If it doesn't return NULL then the pointer that is returned may not be used by anything else than passing to free.

If you dereference the pointer then you will have undefined behavior.


Furthermore, the allocation

char *s = malloc(4);

is not enough to fit a four-character string, as it doesn't have space for the null-terminator.

You also print the contents of the allocated memory, but malloc doesn't initialize its memory in any way, the contents is indeterminate and should be seen as "garbage" or "random". More specifically, there's no guarantee that it will contain a string terminator within those four bytes, which means your printing of its contents is likely to go out of bounds and also lead to undefined behavior.

Then in the foo function you will overwrite the null-terminator, leaving it as merely a sequence of character but not a string in the sense that C thinks it is. That means the next call to foo will go out of bounds of the memory looking for the non-existing terminator, and again lead to undefined behavior.

I recommend you take some time to refresh your text-books and what they say about pointers, strings and malloc. And if they say that malloc(0) should return a NULL pointer, you might consider other books.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • that was the purpose of the foo() function. Go out of bounds on allocated memory and see what happens. – username Nov 26 '22 at 17:00
  • 1
    @username Unfortunately, "see what happens" is kind of pointless with undefined behavior. It might seem to work, it might crash your program, corrupt your OS, or it might set fire to your cat. Well maybe not the last, but with UB there's just no point in see what happens. – Some programmer dude Nov 26 '22 at 17:02