gpt4 book ai didi

c - 尝试 malloc 时具有特定输出的 Valgrind 泄漏和段错误

转载 作者:太空宇宙 更新时间:2023-11-04 01:44:39 24 4
gpt4 key购买 nike

所以我有一个程序接收格式为 a word1 word2 word3 的字符串作为输入,并将这些单词插入到最终进入链表的结构中。对于我尝试过的所有输入,它运行完美,没有内存泄漏,但是对于这个特定的输出,我得到了一个 Segmentation Error 以及内存泄漏,这几乎可以肯定是因为 的长度字 1。这是输入:一个
Adolph_Blaine_Charles_David_Earl_Frederick_Gerald_Hubert_Irvin_John_Kenneth_Lloyd_Martin_Nero_Oliver_Paul_Quincy_Randolph_Sherman_Thomas_Uncas_Victor_William_Xerxes_Yancy_Zeus_Wolfeschlegelsteinhausenbergerdorffwelchevoralternwarengewissenhaftschaferswessenschafewarenwohlgepflegeundsorgfaltigkeitbeschutzenvorangreifendurchihrraubgierigfeindewelchevoralternzwolfhunderttausendjahresvorandieerscheinenvonderersteerdemenschderraumschiffgenachtmittungsteinundsiebeniridiumelektrischmotorsgebrauchlichtalsseinursprungvonkraftgestartseinlangefahrthinzwischensternartigraumaufdersuchennachbarschaftdersternwelchegehabtbewohnbarplanetenkreisedrehensichundwohinderneuerassevonverstandigmenschlichkeitkonntefortpflanzenundsicherfreuenanlebenslanglichfreudeundruhemitnichteinfurchtvorangreifenvorandererintelligentgeschopfsvonhinzwischensternartigraum foo@bar.zp 2

这是我的代码:

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

#define MAXINPUT 682

typedef struct words {
char *word1;
char *word2;
char *word3;
} words;

typedef struct node{
words cont;
struct node *next;
} node;
typedef node *link;

link head;

void add(char c[]) {
words x;
char *str;
link temp = (link)malloc(sizeof(node));
strtok(c, " ");
str = strtok(NULL, " ");
x.word1 = (char *)malloc(sizeof(char) * (strlen(str) + 1));
strcpy(x.word1, str);
str = strtok(NULL, " ");
x.word2 = (char *)malloc(sizeof(char) * (strlen(str) + 1)); /* where the error happens with this input */
strcpy(x.word2, str);
str = strtok(NULL, "\0");
x.word3 = (char *)malloc(sizeof(char) * (strlen(str) + 1));
strcpy(x.word3, str);
temp->cont = x;
temp->next = head;
head = temp;
}

int main() {
char input[MAXINPUT] = " ";
head = NULL;
while (input[0] != 'x') {
fgets(input, MAXINPUT, stdin);
input[strcspn(input, "\r\n")] = 0;
if (input[0] == 'a')
add(input);
...

当我用这段代码运行这个输入时,我得到一个Segmentation Error 并且 valgrind 说有 3 个分配,只有一个空闲,并且泄漏\错误发生在代码中提到的行中,特别是与 strlen。它还说我出于某种原因无法访问内存位置 0x0。我想知道为什么会这样,谢谢!

最佳答案

您无需测试 strtok 是否找到了所有标记。在使用它之前,您必须检查 strtok() 返回的指针。否则,无效输入将导致未定义的行为。

在您的情况下,输入超过 682 个字节,前 681 个字节被读入数组并且该片段不包含足够的标记,使得 strtok() 调用之一返回NULL,当您使用 strlen() 取消引用此空指针时会导致未定义的行为。

始终测试并报告错误情况,您将为自己节省无数小时的调试时间。

当程序崩溃时,valgrind 报告的内存泄漏是没有意义的,因为程序没有完成正常执行,当然也没有正确释放分配的内存。程序退出后内存仍归还给操作系统,但 valgrind 会报告尚未通过调用 free() 释放的 block 。

为避免对行长度设置任意限制,您可以使用 POSIX standard function getline()根据需要重新分配数组。

您还应该使用 strdup 在单个函数调用中分配字符串的副本:

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

typedef struct words {
char *word1;
char *word2;
char *word3;
} words;

typedef struct node{
words cont;
struct node *next;
} node;

typedef node *link; // hiding pointers behind typedefs is not recommended

link head;

link add(char c[]) {
words x = { NULL, NULL, NULL };
char *str;
link temp;

if (strtok(c, " ") != NULL
&& (str = strtok(NULL, " ")) != NULL
&& (x.word1 = strdup(str)) != NULL
&& (str = strtok(NULL, " ")) != NULL
&& (x.word2 = strdup(str)) != NULL
&& (str = strtok(NULL, "")) != NULL
&& (x.word3 = strdup(str)) != NULL
&& (temp = malloc(sizeof(*temp)) != NULL) {
temp->cont = x;
temp->next = head;
return head = temp;
} else {
free(x.word3);
free(x.word2);
free(x.word1);
return NULL;
}
}

int main() {
char *input = NULL;
size_t input_size = 0;

head = NULL;
while (getline(&input, &input_size, stdin) >= 0 && *input != 'x') {
input[strcspn(input, "\r\n")] = '\0';
if (*input == 'a')
add(input);
...
}
...
}
free(input);
...
return 0;
}

关于c - 尝试 malloc 时具有特定输出的 Valgrind 泄漏和段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56011725/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com