【问题标题】:Do not understand why a segfault不明白为什么会出现段错误
【发布时间】:2015-03-23 10:29:05
【问题描述】:

我想前段时间我尝试了以下代码,一切都很顺利。 但是现在,我有一个分段错误,我无法找出哪个部分提供了它。

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

int main() {
    char *test = NULL; // Empty string
    char *a = "programming test";
    int i = 0;

    /* While the string "a" does not encounter a space,
       I put its characters in the empty string "test" one by one. */

    while(a[i] != ' ') {
        test[i] = a[i];
        i++;
    }

    printf("%s\n", test);

    return 0;
}

这个小代码对我来说似乎是正确的,我无法确定哪里出了问题。

【问题讨论】:

  • 您正在取消引用并写入 NULL 指针(带有一些偏移量)。那只会出错。在写入测试之前分配内存并将test指向它。

标签: c arrays pointers segmentation-fault c-strings


【解决方案1】:

你没有在这里分配内存:

char *test = NULL; // Empty string

给它一些记忆:

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

在循环nul 之后终止它:

while(a[i] != ' ') {
    test[i] = a[i];
    i++;
}
test[i] = '\0';
printf("%s\n", test);

【讨论】:

  • 如果我们之后没有 null 终止会发生什么?
  • 以空字符结尾的字符串是存储为包含字符的数组并以空字符('\0',在 ASCII 中称为 NUL)结尾的字符串。它标志着一个字符串/字符数组的结束。
【解决方案2】:

你已经找到了问题的答案,但其他答案没有告诉你的是,你的问题的答案

不明白为什么会出现段错误

是由于您的代码产生的undefined behaviour

在您的代码中,您已将 test 初始化为 NULL

char *test = NULL; // Empty string

稍后,由于没有将内存分配给 test,您试图取消对它的引用。

test[i] = a[i];

这会产生未定义的行为。

来自C11 标准文档,6.5.3.2 章节,地址和间接运算符,第 4 段,

[...] 如果一个 已为指针分配了无效值,一元 * 运算符的行为未定义。

及相关脚注 (102)

一元 * 运算符取消引用指针的无效值包括空指针, 地址与指向的对象类型不恰当地对齐,并且对象的地址在 生命周期结束。

我们知道,数组下标运算符 []unary * 运算符 (*p === p[0] realtion) 的变体,规则同样适用。

所以,基本上,你在这里取消引用 NULL 指针,创建未定义的行为。

记住:>>分段错误是具有未定义行为的副作用之一


要解决此问题,您应该在取消引用之前为指针分配内存。

此外,同样值得一提的是,字符串 应始终以空值结尾。

也就是说,您应该使用int main(void) 作为函数签名。这是标准推荐的。

【讨论】:

    【解决方案3】:
    char * test=NULL;
    

    没有为指针test 分配任何内存。您正在引用NULL 所以会导致分段错误。

    所以为test分配内存。

     test=malloc(50);// memory you need.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      相关资源
      最近更新 更多