我正在尝试创建一个动态的结构数组,我可以成功地为它添加一个结构。但是我添加的任何结构都会导致分段错误。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PEOPLE_BLOCK 4
struct Person {
char *first_name;
char *last_name;
unsigned int age;
};
int add_person(struct Person **people, size_t *people_size, size_t *population, struct Person p) {
if ((sizeof(struct Person) * *population) > *people_size) {
return -1;
}
if ((sizeof(struct Person) * (*population + 1)) >= *people_size) {
*people_size = *people_size + sizeof(struct Person) * PEOPLE_BLOCK;
*people = realloc(*people, *people_size);
if (!*people) {
return -1;
}
}
*people[*population] = p;
++*population;
return 0;
}
int main(int argc, char const *argv[]) {
size_t population;
size_t people_size;
struct Person *people, timn, batman;
population = 0;
people_size = sizeof(struct Person) * PEOPLE_BLOCK;
people = malloc(people_size);
timn.first_name = "Timn";
timn.last_name = "Timothy";
timn.age = 38;
add_person(&people, &people_size, &population, timn);
printf("Person 0's first name: %s\n", people[0].first_name);
batman.first_name = "Bat";
batman.last_name = "Man";
batman.age = 42;
add_person(&people, &people_size, &population, batman);
printf("Person 1's first name: %s\n", people[1].first_name);
free(people);
return 0;
}
我很感激为什么会这样做有任何帮助,谢谢!
答案 0 :(得分:2)
问题在于这一行:
*people[*population] = p;
将其更改为:
(*people)[*population] = p;
为什么要求括号?
编译器有rules of operator precedence。应用它们时,它会将您的代码视为:
*(people[*population]) = p;
这不是你想要的。给定指向指针Type **pp
,
*pp[n] = value;
表示“从n
开始pp
'指针,并在指针所包含的地址取消引用的位置分配value
。换句话说,它实际上意味着:
Type *p = pp[n];
*p = value;
Type *p = *pp;
p[n] = value;
这就是(*pp)[n]
,区分指针与指针的取消引用,给你。没有它,你使用的是无效指针,导致你的错误。
答案 1 :(得分:1)
不确定这个答案是否会有所帮助,但无论如何。 我不明白你的代码,你想要做什么。
您可以直接使用元素数量,指向第一个人的指针以及最大元素数量。你可能会遇到很多问题。
您将文字字符串直接存储在结构中,这意味着在实际情况下(不使用文字)会导致内存泄漏。
这是我的看法。由于测试原因,我把PEOPLE_BLOCK缩小了。 希望这会有所帮助。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PEOPLE_BLOCK 2
typedef struct _Person {
char *first_name;
char *last_name;
unsigned int age;
} Person;
typedef struct _VectorPeople {
Person * people;
size_t num;
size_t max;
} VectorPeople;
void init(VectorPeople *v)
{
v->max = PEOPLE_BLOCK;
v->num = 0;
v->people = (Person *) malloc( sizeof(Person) * v->max );
}
void clear(VectorPeople *v)
{
// Clear persons
Person * it = v->people;
while( ( it - v->people ) < v->num ) {
free( it->first_name );
free( it->last_name );
++it;
}
// Clear vector
v->max = v->num = 0;
free( v->people );
v->people = NULL;
}
void add(VectorPeople *v, Person *p)
{
// Reserve
if ( v->num >= v->max ) {
v->max += PEOPLE_BLOCK;
// Realloc
v->people = realloc( v->people, v->max * sizeof(Person) );
if ( v->people == NULL ) {
exit( -1 );
}
}
// Copy strings
p->first_name = strdup( p->first_name );
p->last_name = strdup( p->last_name );
// Insert
v->people[ ( v->num )++ ] = *p;
}
int main(int argc, char const *argv[]) {
VectorPeople vp;
Person timn;
Person batman;
Person bond;
Person superman;
init( &vp );
timn.first_name = "Timn";
timn.last_name = "Timothy";
timn.age = 38;
add( &vp, &timn );
batman.first_name = "Batn";
batman.last_name = "Man";
batman.age = 42;
add( &vp, &batman );
bond.first_name = "James";
bond.last_name = "Bond";
bond.age = 45;
add( &vp, &bond );
superman.first_name = "Super";
superman.last_name = "Man";
superman.age = 45;
add( &vp, &superman );
int i = 0;
for(; i < vp.num; ++i ) {
printf( "Person: %s, %s.\n", vp.people[ i ].last_name, vp.people[ i ].first_name );
}
clear( &vp );
return 0;
}
答案 2 :(得分:0)
一个问题是add_person()的最后一个参数是具体的,参数&#39;(struct Person)p&#39;。当&#39; timn&#39;和蝙蝠侠&#39;传递到add_person()函数,它们作为原始结构的副本传递。在add_person()结构中,该数据实际上是堆栈上的 ,并且在函数范围之外是volatile。尝试将最后一个参数更改为指针。