【问题标题】:char *str and malloc'ing the memory for str, still getting SEGFAULTchar *str 并为 str 分配内存,仍然得到 SEGFAULT
【发布时间】:2018-01-01 11:05:11
【问题描述】:

我编写了一个小 C 程序来反转字符串。 尽管如此,我还是将str 声明为
字符 *str
然后
str = (char*)malloc(20); str = "this is a test";
但是,如果我使用
char str[20] = "this is a test"

,我不会得到 SEGFAULT
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void swap(char *a, char *b)
{ 
  char temp; 
  temp = *a;
  *a = *b; 
  *b = temp; 
} 

char* reverse(char *str)
{ 
  int len = strlen(str); 
  printf("len = %d \t %s\n", len, str); 
  int i = 0; 

  if (len == 0) 
    return NULL; 
  for (i=0; i<len/2; i++) 
  { 
    swap((str+i), (str+len-1-i));    
    printf("%s\n", str); 
  } 
  return str; 
} 

int main(void)
{ 
  char *str; 
  str = (char *)malloc(20); 
  str = "this is a test"; 

  printf("%s\n", str); 
  reverse(str); 
  printf("%s\n", str); 
  return 0; 
} 

我的理解是,如果我声明,我将获得 SEGFAULT,
char *str="This is a test" 因为它将是一个常量字符串。
所以,我想,当我 malloc 时,str 将从堆中分配,并且这两个函数都可以访问堆内存。但, 仍然出现 SEGFAULT 错误。

【问题讨论】:

  • str = (char*)malloc(20); 34 str = "this is a test";...LEAKKKKKKK
  • str = "this is a test"; --> strcpy(str, "this is a test");
  • 您的编译器不会警告您将字符串字面量指针(即char const *)分配给可修改的字符串指针(char *)的危险。您需要提高警告级别(或使用会警告您的编译器)。
  • 下次不要在代码中添加行号,按原样发布代码。

标签: c arrays string char segmentation-fault


【解决方案1】:

当你这样做时

str = (char*)malloc(20);
str = "this is a test";

重新分配指针str在分配后指向其他地方。

实际上你让它指向一个字符串字面量,它是一个 只读 字符的数组。尝试修改字符串文字会导致未定义的行为

简单的解决方案是改用数组。或者复制到你使用strcpy分配的内存中。

【讨论】:

    【解决方案2】:

    嗯,指针(指向字符串字面量)和数组之间是有区别的,它们是不一样的。 Check the C-FAQ for arrays and pointers 了解更多信息。

    首先,

      str = (char*)malloc(20); 
      str = "this is a test";
    

    导致内存泄漏,因为您正在覆盖malloc() 返回的指针。在这种情况下,malloc() 可以简单地删除,因为您没有将任何内容存储到str 指向的内存位置指针,而是将未命名的const char 数组的基地址存储在指针变量中。

    稍后,当您尝试将指针传递给字符串文字并尝试更改内容时,您会调用 undefined behavior,因为字符串文字是只读的,并且尝试更改它们会导致 UB。

    另一方面,使用char 数组时不会出现问题,因为数组内容是可修改的。

    【讨论】:

      【解决方案3】:
       str = (char*)malloc(20);
       if(NULL != str)
       memcpy(str,"this is a test",(strlen("this is a test") + 1));
      

      【讨论】:

      • "常量字符串地址是该函数的本地地址"
      • 现在这是一个仅代码的答案,没有任何解释,在这里使用 memcpy() 是 a) 不必要的复杂(这就是 strcpy() 的用途)和 b) 如图所示的错误(不复制0 终结者)。感谢您愿意提供答案,但不幸的是,这是一个糟糕的答案。
      • 最后一个参数也应该是MIN(20, strlen("this is a test"))(即使忽略了\0的副本)
      • 这是如何获得投票的?显示的代码错误。结果不是字符串,OP 的代码会将其视为一个字符串。
      猜你喜欢
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 2017-06-30
      • 2021-11-12
      • 2011-04-21
      • 2015-12-21
      相关资源
      最近更新 更多