0

I'm confused. What is the difference between:

char *someFunction(char *src) {
    char str[strlen(src) + 1];
    ...
    return str;
}

and

char *someFunction(char *src) {
    char *str = (char*)malloc((strlen(src) + 1) * sizeof(char));
    ... 
    return str;
}

The first one is with an array (char[]) and second one is with malloc. What I learned in the school is that I should use malloc if I want to make a new char-string within a function. However, it works with char[] also within a function (like first one). The teacher said that we must use the "heap-area", if something must be dynamically allocated. I thought the first one with array (char str[..]) is also dynamic because the size of char[] is not actually known before the program begins (is this the correct understanding!?). This one works by my compiler without any problem.

Please explain the difference easily and tell me some cases where I must use malloc and where I don't need to use it.

trincot
  • 317,000
  • 35
  • 244
  • 286
Nats
  • 31
  • 6

5 Answers5

3

I thought the first one with array(char str[..]) is also dynamically, because the size of char[] is not actually known before the program begins(is it correct understanding!?)

No. You are using variable length array feature of added since . This is not dynamic allocation.
Once the function complete its execution str will no longer exist and returning pointer to it will invoke undefined behavior.

haccks
  • 104,019
  • 25
  • 176
  • 264
2

The difference is simple:

  • The first uses a C99 syntax to allocate a VLA in automatic storage (usually on the stack). This array can only be used for the duration of the function call, you cannot return a pointer to it, it will cause undefined behavior when the caller uses this return value. This version is incorrect.

  • The second allocates an array from the heap, that can be used beyond the end of the function call, until it is explicitly deallocated by free or realloc. This type of allocation is usually referred to as dynamic, the word has a broader meaning in English, but not in this context.

Note that you should simplify the allocation this way:

char *someFunction(char *src) {
    char *str = malloc(strlen(src) + 1);
    .... 
    return str;
}

sizeof(char) is 1 by definition and casting the return value of malloc is usually a bad idea in C, although it is necessary in C++, but other allocation methods are preferred in C++ anyway.

Note that you can get a copy allocated by malloc of src using the Posix function strdup(src).

You should use memory allocated by malloc and its variants when the memory will be used after the end of the current function. If the size if significant, you should also use malloc to avoid invoking undefined behavior by running out of automatic storage. The limit varies from system to system, but with modern environments, automatic storage can usually handle at least one megabyte for all current function invocations, beyond that I recommend using heap storage.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

Using a VLA (the first example) means the array will no longer exist when the function returns. The caller will exhibit undefined behaviour if it attempts to use the function's return value. VLAs are only guaranteed to work with compilers that comply with the 1999 C standard (or later).

Using malloc() (the second example) means that the array will not be deallocated when the function returns (unless your code also explicitly calls free()). So the caller can safely use the return value from that version of the function. The code will work the same with all C standards (from 1989/1990 until today), and even some earlier compilers.

Peter
  • 35,646
  • 4
  • 32
  • 74
0
  • In the first, you are declaring an object with automatic storage duration. So the array lives only as long as the function that calls it exists. In the second , you are getting memory with dynamic storage duration, which means that it will exist until it is explicitly deallocated with free.
  • In C stack is allocated for local variabls and heap is for malloc.So if you declare large array with char str[n], then you might exceed the stack's storage space, which will cause the segfault
Sagar Patel
  • 864
  • 1
  • 11
  • 22
  • Usage of heap and stack are not mentioned in the C standard. What you're describing with that occurs with some compilers, but is not required. And there are some modern compilers/libraries, targeting some host systems (admittedly, systems in less common usage that windows or unix), which simply don't do things that way. – Peter Jan 30 '16 at 11:26
0

When you declare a variable like ckar[something] it is saved in the stack and not in the heap. It's not dynamical allocation. If you want to dynamicaly alocate memmory you should use malloc and the array will be saved in the heap

Vaggelis Spi
  • 164
  • 2
  • 11