为什么这个程序会出现段错误

时间:2010-05-13 20:31:58

标签: c string segmentation-fault reverse

编译并运行这个小程序来反转一个字符串时,我会在任何输出发生之前得到一个Segmentation Fault。请原谅我,如果这是一个显而易见的问题,我对C仍然很新。

#include <stdio.h>

int reverse(char string[], int length); 

int main() {
char string[] = "reversed";

  printf("String at start of main = %s", string);
  reverse(string, sizeof(string));
  printf("%s\n", string);

return 0;

}

// Reverse string 
int reverse(char string[], int length) {
 int i;
 char reversed[] = {};
 int temp;

 for(i = 0; i < length; ++i) {
 temp = string[i];
 reversed[length - i] = temp;

 }
 return 0; 
}

4 个答案:

答案 0 :(得分:6)

因此:

首先创建一个零元素的数组:

char reversed[] = {};

稍后你会尝试写入超出其范围的数组:

reversed[length - i] = temp;

<强>更新

以上意味着您需要分配大小仅在运行时已知的内存(length)。通常的C风格方式是......通过将内存分配的负担推给调用者:

int reverse(const char* string, char* destination, int length);

此函数将写入调用者提供的缓冲区,现在还必须确保:

  1. 缓冲区足够大
  2. 缓冲区的内存应该
  3. 时释放

答案 1 :(得分:3)

虽然它适用于这种情况,但通常,sizeof(string)应该是`strlen(string)。通常,当使用char指针时,sizeof运算符将只返回单个指针的大小 - 而不是整个数组。 。 在reverse()中,你的反向数组没有被分配,你可以像这样分配它:

char* reversed = (char*) malloc( length+1 );

我们在长度上添加一个来解释字符串末尾的空字符。

答案 2 :(得分:1)

您的代码无法编译为C.声明

char reversed[] = {};

无效。在C语言中没有空{}初始化器(它只存在于C ++中)。而且,空的初始化程序在未指定大小的数组声明中没有任何意义(这使得此代码也不能像C ++一样编译),因为在C和C ++中都没有零大小的数组。

要么发布实际代码,要么重新提出问题,如果这应该是C ++。

答案 3 :(得分:0)

在C语言中,你必须仔细考虑变量和数组占用的内存。

当您编写char reversed[] = {}时,您正在创建一个全新的零大小数组。 (这显然不是严格正确的C,但提问者的gcc编译器发生了什么。毕竟,报告在运行时是分段错误而不是编译时的语法错误。)

语句reversed[length - i]然后尝试将数据写入您没有空间的数组元素,因为reversed没有大小。

您有两种选择:

  • 创建一个适当大小的reversed数组(可能使用malloc作为@Bob Kaufman说),然后从reverse()函数返回它。
  • 通过在string内部移动字符来“反转”字符串“就位”。

反转字符串可能更可取 - 如果你动态分配内存,那么你必须担心再次释放它,这可能很痛苦。