【问题标题】:Segmentation fault when assigning int to element of array [closed]将int分配给数组元素时出现分段错误[关闭]
【发布时间】:2016-03-27 13:27:19
【问题描述】:

我的程序的这一部分旨在遍历字符串的chars,并选择字符串中的所有数字并将它们放入一个名为helper 的数组中。这是我正在处理的一个较大程序的一小部分,我已尽力只提供有用的代码段。我也知道没有正确使用指针会导致分段错误,但是我的问题是我找不到错误使用指针的位置。

所以,当我尝试编译以下代码时,我遇到了一个分段错误(核心转储)...

#include <stdio.h>
#include <string.h>

int main(void)
{
    char *eq = "y=344+99";
    int helper[50];
    unsigned short int helperWriter = 0, i;

    for (i = 0; i < eq[i]; i++) //
    {
        if (isdigit(eq[i]))
        {
            unsigned short int d;
            for (d = i; eq[d]; d++)
            {

                if (isdigit(eq[d]))
                {
                    int temp = atoi(eq[d]);
                    helper[helperWriter] = temp;
                    printf("%d", helperWriter);
                }
                helperWriter++; 
            }
        }
    }
}

我对 C 很陌生,反过来,我对指针也很陌生,所以我的错误可能很愚蠢。如果需要任何额外信息,请询问。

【问题讨论】:

  • 试试for (d = i; equation.eq[d]; d++),不然会死循环,最后越界
  • 你做这个作业时helpWriter有多大?
  • 在使用它之前测试索引,并在消息末尾添加newlineif(helpwriter &gt;= 50) { printf("index o/range\n"); }
  • 这是有错误的行:int temp = atoi(eq[d]); 它会导致段错误,因为您忽略了警告。

标签: c arrays string pointers segmentation-fault


【解决方案1】:

当您使用库函数而不包括其原型时,编译器会假设其参数和返回类型为int。你没有#include &lt;stdlib.h&gt;(或ctype.h)所以在这一行

int temp = atoi(eq[d]);

你正在传递一个char,编译器很乐意将它提升为int。但是atoi 需要char* 类型。所以它试图访问机器中低地址的内存,导致段错误。该行应该是

int temp = atoi(eq + d);    // or `atoi(&eq[d])`

将每个字符串字符的地址传递给atoi

第一个循环不正确,你应该测试nul终止符。

helperWriter++; 位于错误位置时也会出错:将其移至将 temp 放入数组的位置下方。

您还忽略了我的建议,即在每条调试消息的末尾加上 newline(以确保在崩溃发生之前实际看到它)。

在您拿起号码然后移过它的方式中可能存在其他错误。您不需要两个嵌套循环,atoi 会将数字转换为下一个非数字字符。

【讨论】:

  • 谢谢,我将努力实现所有这些修复,现在我知道如何在编译时显示警告和错误,我不需要问愚蠢的问题。我对所有人,尤其是 Weather Vane 和 Kemy Land 感到非常抱歉,因为他们不得不为我保持耐心和愚蠢。我从这个“失败”的问题中学到了很多东西,并希望在回答和提问时不会像今天在社区中那样成为沉重的负担。
【解决方案2】:

由于@Weather Vane 指出了您代码中的问题,我想向您展示一个替代解决方案:

#include <stdio.h>          /* printf */
#include <string.h>         /* strcspn */
#include <stdlib.h>         /* strtol */

int main(void)
{
    char *eq = "y=344+99", *ptr = eq;
    int helper[50];
    size_t i = 0;
    while(*ptr) // Is there any more numbers in the string?
    {
        ptr += strcspn(ptr, "1234567890"); // Move ptr to the next number
        helper[i++] = strtol(ptr, &ptr, 10);
        printf("%d\n", helper[i - 1]);
    }
}

虽然这段代码看起来有点复杂,但它更紧​​凑,并且利用了库函数,效率更高。

【讨论】:

  • 虽然我不知道你使用的很多功能,但我一定会研究它们的作用。感谢您提供替代解决方案,效果很好。
  • @TristanArthur 看不懂这个别着急,大家都是从初学者开始的:)
猜你喜欢
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 2016-07-01
相关资源
最近更新 更多