【问题标题】:How can I fix segmentation fault in strcat function? [closed]如何修复 strcat 函数中的分段错误? [关闭]
【发布时间】:2018-04-22 14:46:30
【问题描述】:

我正在尝试将函数指针用作 C 结构的成员。我有 Identity、Person 和 RandomPeople 类型。我的程序以“程序已停止工作”结束。我用 gdb 调试了我的程序,我有以下输出。

[New Thread 18028.0x2c28]
[New Thread 18028.0x4150]
enter the number of people:2
Program received signal SIGSEGV, Segmentation fault.
0x754c5619 in strcat () from C:\WINDOWS\SysWOW64\msvcrt.dll

(可能是 RandomPeople.h 中的 strcat

这是我的程序: Identity struct 可以创建一个识别号并检查给定的识别号。

Identity.h 文件:

#ifndef Identity_H
#define Identity_H
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

struct IDNO {
    char *(*CreateIDNo)(struct IDNO *);   
};

typedef struct IDNO *Id;
Id CreateID();
char *CreateIDNo(Id this);
#endif

Identity.c 文件:

#include "Identity.h"

char *CreateIDNo(Id this) { 
    int str[11]; 
    int totalodd = 0;
    int totaleven = 0;
    this->id = "";

    for (int i = 1; i < 12; i++) {           
        if (i == 1) {
            int n = 1 + rand() % 9;
            totalodd += n;
            str[i - 1] = n;
            continue;
        } else
        if (i != 1 && i % 2 == 0 && i < 10) {
            int n = rand() % 10;
            totaleven += n;
            str[i - 1] = n;
            continue;
        } else
        if (i != 1 && i % 2 != 0 && i < 10) {
            int n = rand() %10;
            totalodd += n;
            str[i - 1] = n;
            continue;
        } else
        if (i == 10) {
            int n11 = (7 * totalodd - totaleven) % 10;
            str[i - 1] = n11;
            continue;
        } else
        if (i == 11) {
            int n12 = (totalodd + totaleven + str[9]) % 10;
            str[i - 1] = n12;
            continue;
        }      
    }
    for (int i = 0; i < 11; i++) {
        char *b; 
        itoa(str[i], b, 10);
        strcat(this->id, b);
    }
    return this->id;
}

每个Person 都有Identity 引用,可以使用此引用创建身份号码。

Person.h 文件:

#ifndef PERSON_H
#define PERSON_H
#include "Identity.h"

struct PERSON {
    Id superid;
};

typedef struct PERSON *Person;
Person CreatePerson();
#endif

Person.c 文件:

#include "Person.h"

Person CreatePerson() {
    Person this;
    this = (Person)malloc(sizeof(struct PERSON));
    this->superid = CreateID();  //Creating my reference    
    return this;
}

RandomPeople.c 文件:

#include "RandomPeople.h"

void CreateRandomPeopleData(RandomPeople k) {
    Person person = CreatePerson();
    char *formatted_identity = person->superid->CreateIDNo(person->superid);
    strcat(data, formatted_identity);       
}   

test.c 文件

int main() {
    RandomPeople rastgelekisiler = CreateRandomPeople();
    rastgelekisiler->CreateRandomPeopleData(rastgelekisiler);
    return 0;
}

编辑:我将这些结构放在我的问题上,因为分段问题可能出现在这些函数指针体中。这些函数可能会返回可能指向错误位置或 null 的 char 指针。我认为这个问题具有最小、完整和可验证的示例。我不希望被否决。

【问题讨论】:

  • 这不是我所说的Minimal, Complete, and Verifiable Example。请尝试将代码缩小到仍然存在问题的最小部分。请记住,如果您想在 strcat 调用中将指针用作目标,则指针需要实际指向可以写入数据的位置。
  • 哦,scanf("%s", ...) 期望输入什么?变量input 是什么? "%s" 格式和 input 匹配吗?
  • 谢谢。我把这些结构放在我的问题上,因为分段问题可能出现在这些函数指针体中。(我从这些函数指针中收集随机数据(字符指针)。)
  • 四种可能:(1)您正在调用strcat(a, b),其中ab 是空指针; (2) 您正在调用strcat(a, b),其中ab 是垃圾值(不指向任何地方); (3) b 指向不是正确的以空字符结尾的字符串的字符; (4) a 指向一个不足以容纳连接字符串的内存区域。 (在这种情况下,4 的可能性较小。)
  • 请阅读minimal reproducible example底部链接的“调试小程序”页面。另外,请考虑minimal reproducible example中的“minimal”这个词。

标签: c struct function-pointers


【解决方案1】:

您在 Identity.c 中这样初始化 this-&gt;idthis-&gt;id = "";

strcat(this-&gt;id, b) 将尝试写入字符串文字 "" 的只读存储,但失败。

顺便说一句,b 在传递给 itoa(str[i], b, 10); 时未初始化,这是未定义行为的另一个计数。

【讨论】:

  • 非常感谢,为什么我不能将未初始化的字符指针传递给 itoa() 函数?
  • @3code: 不,你必须传递一个指向一个足够大的数组的指针,以便接收第一个参数的转换值作为 C 字符串,包括空终止符。
  • @3code:也可以处理您的演示文稿:代码被严重错误地缩进。看看我如何重新格式化您的帖子以使其可读。将指针隐藏在 typedef 后面也被认为是不好的样式和高度错误。您似乎没有掌握指针和数组的概念,与同伴一起学习,正确编写C代码很困难但必须这样做。最后,避免使用this之类的C++关键字作为变量名,这会让读者感到困惑。
  • 'char* b ; malloc(sizeof(char) * (12));itoa (str[i],b,10);'我用这种方式初始化 b。如何用 NULL 终止符初始化 b?
  • @3code: itoa 在它构造的字符串的末尾设置空终止符。在itoa() 调用之后,您可以将b 存储到this-&gt;idthis-&gt;id = b;
猜你喜欢
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2020-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多