我对结构的指针有问题,这些指针的成员也是结构的指针。
浏览建议的类似问题,我发现了这一点:
访问结构指针内的元素 在另一个指向结构的指针内
这里有人建议注意结构的分配记忆。
我认为这在我的代码中正确完成。
typedef struct {
int id_vec;
float *vec_value;
} Vector;
typedef struct cluster{
int id_cluster;
float *centroid;
Vector *patternInCluster;
} Cluster;
int main(void){
Cluster *cluster_ptr= malloc(3 * sizeof(Cluster));
if (cluster_ptr==NULL){
printf("NULL");
}
cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector *));
if (cluster_ptr->patternInCluster==NULL){
printf("NULL");
cluster_ptr->patternInCluster=NULL;
}
float p1[3]={0.0f,1.0f,2.0f};
Vector *somePattern=malloc(2 * sizeof(Vector));
somePattern[0].id_vec=1;
somePattern[0].vec_value=p1;
somePattern[1].id_vec=2;
somePattern[1].vec_value=p1;
}
那么我希望这个陈述有效:
cluster_ptr[1].patternInCluster[1]=somePattern[1];
但它编译并产生分段错误。
意外的是,以下语句未收到错误:
cluster_ptr[0].patternInCluster[1]=somePattern[1];
和一个测试显示正确的结果(somePattern[1] id 和值)
我尝试使用 gdb 进行调试,但我只能看到这个:
Program received signal SIGSEGV, Segmentation fault.
0x00005555555547fe in main () at test_struct.c:36
36 cluster_ptr[1].patternInCluster[1]=somePattern[1];
我是否遗漏了一些分配错误?
这是因为您没有完全填充内容。
此行
cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector *));
等于说
cluster_ptr[0].patternInCluster=malloc(2 * sizeof(Vector *));
实际上,鉴于cluster_ptr
已被分配为 3 Cluster
,在您的代码中执行后者会更清晰。
由于cluster_ptr[1].patternInCluster
尚未获得值,因此尝试取消引用它将导致未定义的行为,但更可能导致分段错误。
您没有分配足够的内存:
cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector *));
由于patternInCluster
是Vector *
类型,你应该分配内存来保存类型Vector
的元素,而不是Vector*
。
cluster_ptr->patternInCluster=malloc(2 * sizeof(Vector));
您的问题是无法访问结构内的指针。你的问题是你如何使用malloc()
。
当你有一个指针时,你只 malloc 一次:
int *pointer = (int* )malloc(sizeof(int));
*pointer = 1;
printf("*pointer:%dn", *pointer);
当你有指针到指针时,你 malloc() 一次用于**pointer_to_pointer
,但你也必须 malloc() 一次用于*pointer_to_pointer
:
int** pointer_to_pointer = (int** )malloc(sizeof(int*));
*pointer_to_pointer = (int* )malloc(sizeof(int));
**pointer_to_pointer = 2;
printf("**pointer:%dn", **pointer_to_pointer);
如果你有多个指针,在**pointer_to_pointer
指向的位置,你需要一个for
循环来为每一个*pointer_to_pointer
分配内存。
for (unsigned int i = 0; i < 3; i++)
{
*(pointer_to_pointer + i*sizeof(int)) = (int* )malloc(sizeof(int));
}
**(pointer_to_pointer + sizeof(int)) = 3;
**(pointer_to_pointer + 2UL*sizeof(int)) = 4;
printf("**(pointer_to_pointer + sizeof(int):%dn", **(pointer_to_pointer + sizeof(int)));
printf("**(pointer_to_pointer + 2UL*sizeof(int):%dn", **(pointer_to_pointer + 2UL*sizeof(int)));
您错误地认为Cluster *cluster_ptr= malloc(3 * sizeof(Cluster));
会自动/神奇地为Cluster[0]
和Cluster[1]
和Cluster[2]
分配内存。
您的语句实际上只为Cluster[0]
分配内存,但足够大 3 Cluster
秒。
因此,修改后的代码将如下所示:
#include <string.h>
#include <stdio.h>
#include <malloc.h>
typedef struct {
int id_vec;
float *vec_value;
} Vector;
typedef struct cluster{
int id_cluster;
float *centroid;
Vector **patternInCluster;
} Cluster;
int main(void){
Cluster **cluster_ptr = (Cluster **)malloc(sizeof(Cluster*));
for (long unsigned int i = 0; i < 3; i++) {
cluster_ptr[i] = (Cluster *)malloc(sizeof(Cluster));
if (cluster_ptr[i]==NULL){
printf("NULL");
}
cluster_ptr[i]->patternInCluster = (Vector **) malloc(sizeof(Vector*));
for (long unsigned int j = 0; j < 3; j++) {
(*cluster_ptr)->patternInCluster[j] = (Vector *) malloc(sizeof(Vector));
if ((*cluster_ptr)->patternInCluster[j]==NULL){
printf("NULL");
(*cluster_ptr)->patternInCluster[j]=NULL;
}
}
}
float p1[3]={0.0f,1.0f,2.0f};
Vector *somePattern= (Vector *) malloc(sizeof(Vector));
somePattern[0].id_vec=1;
somePattern[0].vec_value=p1;
somePattern[1].id_vec=2;
somePattern[1].vec_value=p1;
cluster_ptr[1]->patternInCluster[1] = &somePattern[0];
cluster_ptr[0]->patternInCluster[1] = &somePattern[1];
cluster_ptr[1]->patternInCluster[0] = &somePattern[1];
cluster_ptr[2]->patternInCluster[1] = &somePattern[0];
printf("%dn", cluster_ptr[1]->patternInCluster[1]->id_vec);
printf("%dn", cluster_ptr[0]->patternInCluster[1]->id_vec);
printf("%dn", cluster_ptr[1]->patternInCluster[0]->id_vec);
printf("%dn", cluster_ptr[2]->patternInCluster[1]->id_vec);
return 0;
}
- 在我的系统上,我刚刚编译,它构建和运行没有错误。