1

下面是一个程序的代码:

#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],输出仍然是不正确。有人可以向我解释这个问题吗?非常感谢。

4

6 回答 6

6

char s[strlen(q)]是一个局部变量,因此当您返回它的地址时,它会导致未定义的行为。因此,您可以使用strdup()malloc()动态分配数组,从而确保当您从函数返回时数组 s 在堆上可用。返回的数组也需要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;
}
于 2013-05-27T05:18:18.333 回答
3
char s[strlen(q)];

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

于 2013-05-27T05:22:29.863 回答
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;
}
于 2013-05-27T05:30:46.313 回答
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;
}
于 2013-05-27T06:26:05.257 回答
0

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

例如:

 char *test;

    test = (char *)malloc(sizeof(char)*Multiply_By);
于 2013-05-27T05:17:07.203 回答
-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];

您还需要在使用后释放它。也许会成为内存泄漏。

希望这可以帮助你。

于 2013-05-27T05:25:29.477 回答