我在指针上有麻烦了。我的程序有很多指针,其中大多数是正确工作的,但我试图在一个结构数组中添加一个指针数组,该数组指向同一个结构数组中的不同成员。这应该有点像链接列表,但也有数组的好处。需要动态分配数组,因为数据是包含元素的结构数组,其中包含元素的结构数组,其中的元素是基本类型的数组,其数量为每个未知值,直到运行时为止。我尝试过使用静态分配数组来保存所有的数据,但结果却是很多兆字节。
我在下面创建了一个精简的测试程序,它只包含了我有困难的部分。
在groups[0].sub_group[0] = groups[1];行中,我试图将指向groups[1]地址的指针分配到groups[0].sub_group中。这确实编译了,但它提供了一个运行时错误'EXE_BAD_ACCESS‘。我认为行应该是groups[0].sub_group[0] = &groups[1];,但这甚至不编译。
最终,我想要在函数内部运行这个任务,所以我还需要能够使用指向组的指针来完成这个任务,比如(*p_groups)[0].sub_group[0] = groups[1];,但是这也不起作用。
我也想问一个相关的问题:
(*p_groups)[0].sub_group[0] = groups[1];和
p_groups[0]->sub_group[0] = groups[1];?
任何帮助都将不胜感激。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char * text;
int data_type_count; // count of elements in data_type_list
char * bacnet_name; // string of name
} pup_item_t;
typedef struct pup_group_t pup_group_t;
struct pup_group_t {
char * title; // Null Title indicates end of list
pup_item_t * items; // array of items
int item_count; //count of items
pup_group_t * sub_group; // array of pointers to associated sub groups
int sub_group_count; // count of sub groups
};
typedef pup_group_t * pup_group_array_t;
int main(int argc, const char * argv[])
{
pup_group_array_t groups = (pup_group_t *)malloc(sizeof(pup_group_t) * 2);
groups[0].items = (pup_item_t *)malloc(sizeof(pup_item_t)*2);
groups[1].items = (pup_item_t *)malloc(sizeof(pup_item_t)*2);
pup_group_array_t * p_groups;
p_groups = &groups;
groups[0].items[0].text = strdup("Group 0 Text 0");
groups[0].items[1].text = strdup("Group 0 Text 1");
groups[1].items[0].text = strdup("Group 1 Text 0");
groups[1].items[1].text = strdup("Group 1 Text 1");
groups[0].sub_group[0] = groups[1]; // <-- EXE_BAD_ACCESS (code = 1, address = 0x0)
(*p_groups)[0].sub_group[0] = groups[1]; // <-- EXE_BAD_ACCESS (code = 1, address = 0x0)
printf("%s \n",groups[0].items[0].text); // prints "Group 0 Text 0"
printf("%s \n",groups[1].items[1].text); // prints "Group 1 Text 1"
printf("%s \n",groups[0].sub_group->items[1].text); // <-- EXE_BAD_ACCESS (code = 1, address = 0x8)
// should print "Group 1 Text 1"
return 0;
}更新6/30/2014
在我的示例代码中,您是对的,我忘了使用malloc sub_group。然而,在我的实时代码中,我并没有忘记这样做。我的实时代码是几千行,太大了,不能在这里发布。我已经编辑了示例代码,以更接近我的活代码。示例代码现在编译并正确工作(据我所知)。但我的活代码不会执行。
下面是更新的示例代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char * text;
int data_type_count; // count of elements in data_type_list
char * bacnet_name; // string of name
} pup_item_t;
typedef struct pup_group_t pup_group_t;
struct pup_group_t {
char * title; // Null Title indicates end of list
pup_item_t * items; // array of items
int item_count; //count of items
pup_group_t * sub_group; // array of pointers to associated sub groups
int sub_group_count; // count of sub groups
};
typedef pup_group_t * pup_group_array_t;
void allocate_groups(pup_group_array_t * p_groups) {
*p_groups = (pup_group_t *)malloc(sizeof(pup_group_t) * 2);
p_groups[0]->items = (pup_item_t *)malloc(sizeof(pup_item_t) *2 );
p_groups[1]->items = (pup_item_t *)malloc(sizeof(pup_item_t) *2 );
p_groups[0]->sub_group = (pup_group_t *)malloc(sizeof(pup_group_t)* 2);
}
void assign_groups(pup_group_array_t * p_groups) {
p_groups[0]->items[0].text = strdup("Group 0 Text 0");
p_groups[0]->items[1].text = strdup("Group 0 Text 1");
p_groups[1]->items[0].text = strdup("Group 1 Text 0");
p_groups[1]->items[1].text = strdup("Group 1 Text 1");
p_groups[0]->sub_group[0] = *p_groups[1];
}
void print_groups(pup_group_array_t * p_groups) {
printf("%s \n",p_groups[0]->items[0].text); // prints "Group 0 Text 0"
printf("%s \n",p_groups[1]->items[1].text); // prints "Group 1 Text 1"
printf("%s \n",p_groups[0]->sub_group[0].items[1].text);// prints "Group 1 Text 1"
}
int main(int argc, const char * argv[])
{
pup_group_array_t groups = NULL;
allocate_groups(&groups);
assign_groups(&groups);
print_groups(&groups);
return 0;
}下面是我的实时代码中运行时崩溃的部分:
int allocate_groups_array(char * filename, pup_group_array_t * p_groups, int * p_bacnet_count) {
int i, size;
int item[MAX_GROUPS_PER_FILE] = {0};
int levels[MAX_GROUPS_PER_FILE] = {0};
int count = scan_pup_file("ct9-103.pup", item, levels, p_bacnet_count);
*p_groups = (pup_group_t *)malloc(sizeof(pup_group_t)*(count+1));
for (i = 0; i <= count; i++) {
size = sizeof(pup_item_t) * (item[i]);
p_groups[i]->items = (pup_item_t *)malloc(size); // EXC_BAD_ACCESS (code=1, address = 0x18)
printf("group %d is level %d has %d items with size of %d \n",i,levels[i],item[i], size);
}
assign_sub_groups (p_groups, count, item, levels);
return count;
}大小和其他变量的值是正确的。但是malloc p_groups[i]->items = (pup_item_t *)malloc(size);返回EXC_BAD_ACCESS。我做错了什么?
**更新6/30/2014下午**
以下是有人帮助我的工作版本:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char * text;
int data_type_count; // count of elements in data_type_list
char * bacnet_name; // string of name
} pup_item_t;
typedef struct pup_group_t pup_group_t;
struct pup_group_t {
char * title; // Null Title indicates end of list
pup_item_t * items; // array of items
int item_count; //count of items
pup_group_t * sub_group; // array of pointers to associated sub groups
int sub_group_count; // count of sub groups
};
//typedef pup_group_t * pup_group_array_t;
pup_group_t * allocate_groups() {
pup_group_t * p_groups = (pup_group_t *)calloc(sizeof(pup_group_t) , 201);
p_groups[0].items = (pup_item_t *)malloc(sizeof(pup_item_t) *201 );
p_groups[1].items = (pup_item_t *)malloc(sizeof(pup_item_t) *201 );
p_groups[200].items = (pup_item_t *)malloc(sizeof(pup_item_t) *201 );
p_groups[0].sub_group = (pup_group_t *)malloc(sizeof(pup_group_t *)* 201);
return p_groups;
}
void assign_groups(pup_group_t * p_groups) {
p_groups[0].items[0].text = "Group 0 Text 0";
p_groups[200].items[0].text = "Group 200 Text 1";
p_groups[1].items[200].text = "Group 1 Text 200";
p_groups[1].items[200].text = "Group 1 Text 200";
p_groups[200].items[200].text = "Group 200 Text 200";
p_groups[0].sub_group[0] = p_groups[200];
}
void print_groups(pup_group_t * p_groups) {
printf("%s \n",p_groups[0].items[0].text); // prints "Group 0 Text 0"
printf("%s \n",p_groups[200].items[0].text); // prints "Group 200 Text 1"
printf("%s \n",p_groups[0].sub_group[0].items[200].text); // prints "Group 200 Text 200"
}
int main(int argc, const char * argv[])
{
pup_group_t * groups = allocate_groups();
assign_groups(groups);
print_groups(groups);
return 0;
}发布于 2014-06-30 02:14:59
您没有为sub_group成员变量分配任何存储空间。你也需要malloc。
编辑更新代码:对于真正的代码,我担心这可能更难诊断。
看看你能不能访问items成员,哦,等一下。p_groups是一个隐藏的指针,所以你有一个双指针.它是一个指向数组的指针。所以不应该是:
(*p_groups)[i].items = ...?我认为您可能正在破坏您的内存,而且可能是malloc本身找不到它的元数据。您还可以将强制转换丢失给malloc,这在C中是不必要的。
我也想问一个相关的问题:
(*p_groups)[0].sub_group[0] = groups[1]; and
p_groups[0]->sub_group[0] = groups[1]; ?是。我注意到你已经怀疑过这种事了。区别在于,第一行访问指向数组的指针,第二行访问指针数组。它们都是双向的,但它们将数组放置在不同的位置。
如果我们将第二个表达式重写为类似的括号形式,则会更容易看到,
(*p_groups[0]).sub_groups[0] = groups[1];后缀操作符首先应用,所以它等同于这个。
(*(p_groups[0])).sub_groups[0] = groups[1];小的测试可能会误导人,因为索引0会起作用。*E == *(E+0) == E[0].而其他“小”指数可能不会太超出界限,不会引起严重的麻烦。但是会发生一些奇怪的事情,你可能已经经历过了。更改一行可以修复一些问题,即使更改不应该真正改变任何事情,类似的事情,这就是内存碎片的作用。
如果你能原谅一些艺术,
[ -> ]
[ -> ]
[ -> ]
[ -> ]
-> [ ]
[ ]
[ ]
[ ]https://stackoverflow.com/questions/24482090
复制相似问题