CrazyHenry
CrazyHenry

Reputation: 31

Dynamic and static char array

Here are the codes of a program:

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

char * cloning(char * q){
    char s[strlen(q)];
    int i;
    for(i = 0; i < strlen(q); i++)
        s[i] = q[i];
    return s;
}

int main(){
    char q[] = "hello";
    char *s = cloning(q);
    return 0;
}

After the compilation a warning appears, so I changed the returned value like this:

char *b = s;
return b;

In this way the warning can be solved. However I found that inside the function cloning(), sizeof(s) is 5, but strlen(s) is 7. And if I change char s[strlen(q)] simply to char s[5], the output is still incorrect. Can anybody explain this problem to me? Thank you very much.

Upvotes: 1

Views: 9789

Answers (6)

Lundin
Lundin

Reputation: 213832

The proper way to do this with standard C, no matter version of the C standard, is this:

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

char* cloning (const char* str)
{
  char*  clone;
  size_t size = strlen(str) + 1;

  clone = malloc(size);
  if(clone == NULL)
  {
    return NULL;
  }

  memcpy(clone, str, size); 

  return clone;
}

int main(){
    char original[] = "hello";
    char* clone = cloning(original);

    if(clone == NULL)
    {
      puts("Heap allocation failed.");
      return 0;
    }

    puts(clone);

    free(clone);
    return 0;
}

Upvotes: 2

Binayaka Chakraborty
Binayaka Chakraborty

Reputation: 1335

char s[strlen(q)] is a local variable, and hence when you return its address, it results in undefined behaviour. Thus either you could use strdup() or malloc() to dynamically allocate the array, thus ensuring that the array s is available on the heap when you return from the function. The returned array would need to be free()-ed as well, else it would have a memory leak :)

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

char * cloning(char * q){
    char *s = malloc(strlen(q)+1);
    // if you write char s[strlen(q)], it is defined locally, and thus on return gives an undefined behaviour
    int i;
    for(i = 0; i < strlen(q)+1; i++)
        s[i] = q[i];
    return s;
}

int main(){
    char q[] = "hello";
    char *s = cloning(q);
    free(s);
    return 0;
}

Upvotes: 6

Mantra
Mantra

Reputation: 346

Dynamic arrays in C are declared using Malloc and Calloc. Try googling it.

Eg:

 char *test;

    test = (char *)malloc(sizeof(char)*Multiply_By);

Upvotes: 0

AndersK
AndersK

Reputation: 36082

multiple issues with this code:

char * cloning(char * q){  
    char s[strlen(q)]; // s has strlen size but needs strlen + 1 to hold \0
    int i;
    for(i = 0; i < strlen(q); i++) // should copy the \0 otherwise q is not a valid string
        s[i] = q[i];
    return s;// returns the address of a local var == undef. behavior
}

if you want to clone a string just do strdup()

char* cloning(char* q)
{
  return strdup(q);
}

or the equivalent

char * cloning(char * q)
{
    char* s = malloc(strlen(q)+1);
    int i;
    for(i = 0; i < strlen(q)+1; i++)
        s[i] = q[i];
    return s;
}

Upvotes: 3

vonnyfly
vonnyfly

Reputation: 7

In C,static array is in stack,after function return,it's been destoryed. and string with char has a '\0' end. But strlen don't include it. For example.char q[] = "hello"; strlen(q) = 5,but the real size is 6 If you want to copy a string, the last '\0' must be added at the end.or using

char *s = malloc(sizeof(q)); ...; for(i = 0; i < sizeof(q); i++) s[i] = q[i];

you also need to free it after using.Maybe become a mem leak.

Hope this can help u.

Upvotes: -1

user2404501
user2404501

Reputation:

char s[strlen(q)];

is a variable-length array. Like a malloc'ed buffer its size is determined at runtime. Unlike a malloc'ed buffer, it ceases to exist when the function returns.

Upvotes: 3

Related Questions