动态和静态char数组

时间:2013-05-27 05:12:18

标签: c arrays string

以下是程序的代码:

#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;
}

编译后出现警告,所以我更改了返回的值:

char *b = s;
return b;

通过这种方式可以解决警告问题。但是我发现在函数cloning()中,sizeof(s)是5,但是strlen(s)是7.如果我将char s [strlen(q)]简单地改为char s [5],输出仍然是不正确。有人可以向我解释这个问题吗?非常感谢你。

6 个答案:

答案 0 :(得分:6)

char s[strlen(q)]是一个局部变量,因此当您返回其地址时,会导致未定义的行为。因此,您可以使用strdup()malloc()来动态分配数组,从而确保从函数返回时堆上的数组可用。返回的数组也需要free() - ed,否则会有内存泄漏:)

#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;
}

答案 1 :(得分:3)

char s[strlen(q)];

是一个可变长度数组。像malloc的缓冲区一样,它的大小在运行时确定。与malloc的缓冲区不同,它在函数返回时不再存在。

答案 2 :(得分:3)

此代码存在多个问题:

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
}

如果要克隆字符串,请执行strdup()

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

或等效的

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;
}

答案 3 :(得分:2)

使用标准C执行此操作的正确方法,无论C标准的版本如何,都是:

#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;
}

答案 4 :(得分:0)

C中的动态数组使用Malloc和Calloc声明。尝试谷歌搜索。

例如:

 char *test;

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

答案 5 :(得分:-1)

在C中,静态数组在堆栈中,在函数返回后,它已被破坏。和带有char的字符串有一个'\ 0'结尾。但是strlen不包含它。例如。char q[] = "hello"; strlen(q) = 5,but the real size is 6 如果要复制字符串,则必须在结尾添加最后一个'\ 0'。使用

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

使用后你也需要释放它。可能会成为一个内存泄漏。

希望这可以帮到你。