【发布时间】:2014-11-20 17:24:51
【问题描述】:
所以...过去我被告知我的问题不好...我相信主要是因为我没有足够好地隔离有问题的代码。我会尽力在这篇文章中提出一个尖锐、简洁、中肯的问题。我当然愿意接受有关如何更好地提出我的问题的建议。 谢谢。
我正在使用 C 语言开发一个小项目,该项目将作为我已经研究了一段时间的大型、有缺陷的程序的原型。我正在尝试首先在一个较小的程序中解决细节。我有两个结构:
struct list
{
char ownerName[20];
int ownerAge;
char sex;
}owner;
和
struct list2
{
char petName[20];
char owner[20];
char animal[4];
char breed[50];
char color[20];
}pets;
该程序应该从用户输入中获取 ownerName 并将其与 pets 结构中的“.owner”进行比较。然后将 ownerName 和 petName 元素复制到一个数组中,并将所有者和他/她的宠物的名字打印在一个列表中。虽然我知道我不需要所有者结构来完成此操作,但我正在使用它来模拟我正在编写的其他程序。
我正在使用
if (strcmp(pets[i].owner, name) == 0)
比较结构元素,似乎这部分已经下来了。
变量 j 统计满足这个条件的记录数,变量 l = j + 1。我调用数组使用:
char *petsList[l];
数组的大小由 l (j + 1) 决定,因为我需要 j 个元素作为 petNames + 1 个元素作为所有者名称。
我还通过以下方法创建了一个指向 petsList 数组的指针:
char *(*ptr)[l] = &petsList
通过以下命令将所有者名称添加到数组中:
(*ptr)[0] = (char *)malloc(sizeof(name));
strcpy ( (*ptr)[0], name);
使用 for 循环将 petNames 添加到数组 petsList 中。我已初始化 i = 1 以防止 petsList[0] 被覆盖,并尝试通过以下循环将 petNames 写入数组:
i = 1;
for (k=0; k < PETS; k++)
{
if (strcmp(pets[k].owner, name) == 0)
{
(*ptr)[i] = (char *)malloc(sizeof(pets[k].petName));
if (!*(ptr)[i])
{
puts("\nMemory Allocation Error");
exit (1);
}
strcpy( (*ptr)[i], pets[k].petName);
i++;
}
}
假设对于给定的名称输入,我得到了三个匹配的宠物。循环迭代前两次就好了,但是在循环的第三次迭代中,我得到了内存分配错误。这始终发生在循环的最后一次迭代中。例如,如果我有 2 只宠物与 ownerName 关联,则列表将在第一次迭代中正常运行,而在第二次迭代中失败;如果我有 4 只宠物与 ownerName 相关联,则循环将在前 3 次正常运行并在第四次失败,因此循环的最终迭代似乎始终失败。我已经尝试过多次更改代码,但现在我不知道如何继续使用这个程序。任何帮助是极大的赞赏。
谢谢。
【问题讨论】:
-
*ptr数组的大小是多少?i是有效索引吗?还有in C you should not cast the return ofmalloc. -
valgrind必须说明程序做错了什么。 VLA 的动态分配是可行的,但很棘手;我必须非常努力地查看代码才能知道它是否正确并且现在没有时间。请考虑 MCVE (Minimal, Complete, Verifiable Example) 或 SSCCE (Short, Self-Contained, Correct Example) 的优点。 -
sizeof(name)获取的不是字符串的长度,而是char *的大小。试试malloc(strlen(name)+1)。另外,为什么你需要一个指向petsList的指针而不是直接使用它?如果你这样做了,你可以使用char **ptr = petsList;并使用ptr[i]访问ithchar *,这可能更容易(阅读和使用)。像您这样的数组指针可能对数组数组更有意义,但这不是您所拥有的。 -
这个问题还是太长了。为了演示内存分配,我们真的需要了解宠物名称、品种和颜色吗?
-
@JoachimPileborg 未设置数组的大小。如果 3 个宠物名称与所有者相关联,则数组大小为 4,其中 3 个用于 petNames,1 个用于 ownerName。我使用 j 来计算匹配 petNames 的实例,并使用 l(等于 j + 1)来声明数组的大小。我相信 i 是一个有效的索引;它似乎在循环中迭代了几次。什么会使 i 作为索引无效?感谢您的回复。
标签: c arrays memory-management struct