C 分段错误:函数 strcmp 之间的内存更改
C Segmentation fault: memory altered between functions strcmp
如果有人能告诉我为什么在 populate() returns 目录后我无法访问 dir.paths[dir.npaths] 的内存,以及如何修复它。那将不胜感激。
这是问题的简化,它浓缩了所有核心要素。我只需要知道如何在不出现分段错误的情况下进行比较。
比较实际上是用在if语句中。例如。如果 (strcmp(dir..., "file") == 0)
seek,在完整程序中,调用populate,变成递归调用。这意味着我不能只将 strcmp 移动到填充函数中。他们需要分开。
// 测试从函数 populate
开始
// seek()函数中的strcmp导致段错误
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
string name;
string type;
}
path;
typedef struct
{
int npaths;
path* paths;
}
directory;
// 原型
int seek(directory dir);
int main(void)
{
directory dir;
seek(dir);
}
// 实际测试在这条线以下
directory populate(directory dir)
{
path newPath = {.name = "file/", .type = "directory"};
dir.paths[dir.npaths] = newPath;
return dir;
}
int seek(directory dir)
{
populate(dir);
printf("Should return 0\n");
// Supposedly accesses memory it shouldn't
printf("%i\n", strcmp(dir.paths[dir.npaths].type, "directory"));
return 0;
}
// 如果你足够酷,想深入了解实际代码,谢谢。
// 这是一个 link 到 pastebin。 https://pastebin.com/j8y652GD
dir = populate(dir);
或许可以解决您的问题。
如果你在populate(dir)
行设置断点,你会看到执行该行后目录保持不变。
因为你的函数 populate 的参数是 struct 类型,所以传入 populate 正是 dir.
的副本
dir.paths[dir.npaths] = newPath;
愚蠢的问题,但是你在某处为 dir.paths[]
分配内存吗?如果没有,你必须调用 dir.paths = calloc (count, sizeof(path))
或 malloc (count * sizeof(path))
具有相同的效果。
就像@code_farmer 指出的那样,您将 dir
中包含的数据按值传递给 populate
,然后数据被复制到堆栈。当然,没有人负责将栈上数据复制回来。没有人应该。您必须按照@code_farmer 的建议调用populate
。我什至建议您在将结构作为参数传递时使用指针,以减少内存占用,让您在这种情况下生活更轻松。
hth
如果有人能告诉我为什么在 populate() returns 目录后我无法访问 dir.paths[dir.npaths] 的内存,以及如何修复它。那将不胜感激。
这是问题的简化,它浓缩了所有核心要素。我只需要知道如何在不出现分段错误的情况下进行比较。
比较实际上是用在if语句中。例如。如果 (strcmp(dir..., "file") == 0)
seek,在完整程序中,调用populate,变成递归调用。这意味着我不能只将 strcmp 移动到填充函数中。他们需要分开。
// 测试从函数 populate
开始// seek()函数中的strcmp导致段错误
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
string name;
string type;
}
path;
typedef struct
{
int npaths;
path* paths;
}
directory;
// 原型
int seek(directory dir);
int main(void)
{
directory dir;
seek(dir);
}
// 实际测试在这条线以下
directory populate(directory dir)
{
path newPath = {.name = "file/", .type = "directory"};
dir.paths[dir.npaths] = newPath;
return dir;
}
int seek(directory dir)
{
populate(dir);
printf("Should return 0\n");
// Supposedly accesses memory it shouldn't
printf("%i\n", strcmp(dir.paths[dir.npaths].type, "directory"));
return 0;
}
// 如果你足够酷,想深入了解实际代码,谢谢。
// 这是一个 link 到 pastebin。 https://pastebin.com/j8y652GD
dir = populate(dir);
或许可以解决您的问题。
如果你在populate(dir)
行设置断点,你会看到执行该行后目录保持不变。
因为你的函数 populate 的参数是 struct 类型,所以传入 populate 正是 dir.
的副本dir.paths[dir.npaths] = newPath;
愚蠢的问题,但是你在某处为 dir.paths[]
分配内存吗?如果没有,你必须调用 dir.paths = calloc (count, sizeof(path))
或 malloc (count * sizeof(path))
具有相同的效果。
就像@code_farmer 指出的那样,您将 dir
中包含的数据按值传递给 populate
,然后数据被复制到堆栈。当然,没有人负责将栈上数据复制回来。没有人应该。您必须按照@code_farmer 的建议调用populate
。我什至建议您在将结构作为参数传递时使用指针,以减少内存占用,让您在这种情况下生活更轻松。
hth