如何在c中遍历Struct数组

时间:2014-03-12 08:53:45

标签: c arrays struct segmentation-fault

我有一个程序,它创建一个数组或结构,并通过它进行处理。最初它使用定义的nyumber元素初始化数组。然后,对于数组中的一些元素,将分配名称。

我假装代码与我在codebloc中测试的场景相同并得到类似的错误。问题在评论中有所描述。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _car {
    char *name;
    int year;
} Car;

char *getCarName(char *name, int var);
void processCar();
void printCars(Car car[]);
int INCREMENT = 10;

int main(void)
{
    processCar();
    return 0;
}

void processCar()
{
    // create car array with amount of INCREMENT
    Car CAR_ARRAY[INCREMENT];
    int a=0;
    // This function assign name for Car amount 10 less than INCREMENT
    while (a<INCREMENT - 2) {
        char *carName;
        carName = getCarName(&carName, a);

        CAR_ARRAY[a].name = malloc(strlen(carName) + 1);
        strcpy(CAR_ARRAY[a].name, carName);
        a++;
    }

     printCars(CAR_ARRAY);
}

void printCars(Car car[])
{
    printf("IN Car \n");
    int a = 0;
    // when try to call name for car amount equals to INCREMENT program terminates.
    while(a<INCREMENT) {
        if (car[a].name != NULL) // checking if NULL
            printf("Car Name : %d -> %s\n", a, car[a].name);
        a++;
    }
}

char *getCarName(char *name, int var)
{
    name = "Toyota";
    return name;
}

检查struct array上的struct值是否可以调用它的正确方法是什么?

修改

我创建了一个hack来执行此操作,如下所示。

// added these right after creating array
for (a = 0; a < INCREMENT; a++)
    CAR_ARRAY[a].name = NULL;

我不知道这是否是一种标准方式。请咨询。

1 个答案:

答案 0 :(得分:2)

你在打印之前正在检查NULL,这是一个好主意,但它对你没有帮助,因为你的最后两辆车没有初始化并且可能包含垃圾:name指针是不是NULL,但也没有指向有效地址。随后发生分段违规。

您应该初始化所有汽车,而不仅仅是INCREMENT - 2。或者,您可以在初始化之前调用memset将您的汽车初始化为零:

memset(CAR_ARRAY, 0, sizeof(Car) * INCREMENT);

顺便说一下,你处理getCarName的方式也相当不稳定。目前,您的名字是指向字符串文字的指针。你的本地变量carName做了一个半心半意的双重任务:你试图通过引用传递它(但实际上你没有)并且你也返回它。

基本上,您可以通过以下两种方式之一完成此操作。这里更容易的是返回一个指针。在这种情况下,您不必传递任何字符串:

char *getCarName(int var)
{
    static char *names[3] = {"Toyota", "Dodge", "Peugeot"};
    return names[var % 3];
}

并称之为:

char *carName = getCarName(&carName, a);    

或者,您可以通过引用传递char指针,即作为指向char的指针。在这种情况下,您不必返回任何内容:

void getCarName(char **name, int var)
{
    static char* names[3] = {"Toyota", "Dodge", "Peugeot"};
    *name = names[var % 3];
}

这样称呼:

char *carName;
getCarName(&carName, a);

这里还有其他一些场景,例如,如果你只是传递一个char指针并让getCarName填充它,但我现在就把它留下来 - 它会让一切变得更加复杂。