所以...过去我被告知我的问题并不好......我相信这主要是因为我还没有把问题代码隔离得太好。我会尽力在这篇文章中提出一个尖锐,简洁,重要的问题。我当然愿意接受有关如何更好地提出问题的建议。 谢谢。
我正在研究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;
该程序应该从用户输入fgets ownerName并将其与" .owner"在宠物结构中。然后应将ownerName和petName元素复制到一个数组中,并将所有者和他/她的宠物的名称打印在一个列表中。虽然我知道我不需要所有者结构来实现这一点,但我使用它来模拟我正在编写的其他程序。
我正在使用
if (strcmp(pets[i].owner, name) == 0)
比较结构元素,似乎有这个部分。
变量j计算满足此条件的记录数,变量l = j + 1.我使用以下方法调用数组:
char *petsList[l];
数组的大小由l(j + 1)决定,因为我需要为所有者名称的petNames + 1元素使用j个元素。
我还通过以下方式创建了一个指向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次运行正常并在第4次失败,因此看起来循环的最终迭代始终失败。我曾尝试多次更改代码,但现在我不知道如何继续使用这个程序。任何帮助是极大的赞赏。
感谢。
答案 0 :(得分:0)
这有点奇怪。也许:
if(!*(ptr)[i])
应该是
if(!(*ptr)[i])
答案 1 :(得分:0)
不要施放malloc返回值。
因为我不能用最小的例子来检查。
char *(*ptr)[l] = &petsList
为什么要制作如此复杂的构造?我甚至不确定它应该完成什么。你想让第一个索引和下一个索引中的所有宠物都包含所有者吗?这可以通过petslist
最后你真正需要什么结构?
是这样的:
数组:
0 = owner
1 = pet 1
2 = pet 2
或类似
0,0 = owner 1,0 = owner 2 etc.
0,1 = pet 1 1,1 = pet 3
0,2 = pet 2 1,2 = pet 4
好的,这是一个你想做的工作实例。您可以轻松扩展它以执行第二种数据安排。如果您有任何问题,请随时提出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PETAMOUNT 40
struct list2
{
char petName[20];
char owner[20];
char animal[4];
char breed[50];
char color[20];
};
int main() {
struct list2 *pets; // list of all pets
char name[128]; // contain name of the owner, get from stdin
unsigned int i; // i and j are both counter variable
unsigned int j;
fgets(name, 128, stdin); // get string from stdin
name[strlen(name) - 1] = '\0'; // remove newline
pets = malloc(PETAMOUNT * sizeof(struct list2)); // allocate memory for the list of all pets
if (pets == NULL) {
printf("malloc err\n");
exit(1);
}
for (i = 0; i < PETAMOUNT; i++) { // initialize some pets and some owners
strcpy(pets[i].petName, "petname ");
strcpy(pets[i].owner, "owner ");
pets[i].petName[7] = i + '0'; // there are PETAMOUNT of petnames. petname0, petname1 etc
pets[i].owner[5] = (i / 4) + '0'; // there are PETAMOUNT / 4 owners. owner0 has petname0 to petname3, owner1 has petname4 to 7 etc
}
char ***petslist; // a list of list of strings or 3d char array
petslist = malloc(sizeof(char **)); // allocate pointer to contain a double array
petslist[0] = malloc(sizeof(char *)); // allocate a pointer to contain the name of the owner
if (petslist[0] == NULL) {
printf("malloc err\n");
exit(1);
}
petslist[0][0] = malloc(strlen(name) + 1); // allocate memory to contain the owner
if (petslist[0][0] == NULL) {
printf("malloc err\n");
exit(1);
}
strcpy(petslist[0][0], name); // copy owner into the first index
for (i = 0, j = 1; i < PETAMOUNT; i++) { // go through all pets
if (strcmp(pets[i].owner, name) == 0) { // if the owner of the current pet is the same as the inputted owner
petslist[0] = realloc(petslist[0], (j + 1) * sizeof(char *)); // allocate pointer for the next pet
petslist[0][j] = malloc(strlen(pets[i].petName) + 1); // allocate memory to contain the chars of the pet
if (petslist[0][j] == NULL) {
printf("malloc err\n");
exit(1);
}
strcpy(petslist[0][j], pets[i].petName); // copy the petname into the array
j++;
}
}
puts("petslist:"); // print it all out
for (i = 0; i < j; i++) {
printf("|%s|\n", petslist[0][i]);
}
exit(0);
}
目前我总是写到[0] [0],但是如果你重新分配,你可以在那之后腾出更多空间