在C中使用堆栈

时间:2015-10-09 19:46:20

标签: c pointers struct segmentation-fault

经过几个小时的努力尝试自己调试这段代码后,我放弃了寻求帮助。我创建了一个程序,旨在保存我选择的“记录”,结构,并显示我知道如何在内存中利用/操纵它们。在我的代码中,我制作了一个汽车库存,允许您添加,删除和打印结构。我的结构如下所示:

struct car{
    char *make;
    char *model;
    int year;
    int mpg;
    int mileage;
    int cost;
};

我使用一个数字菜单系统,允许用户选择如何处理结构。无论如何,我遇到了这个问题:

我可以添加两个结构并将它们全部打印出来。但是,如果我添加两个以上的结构,而不是遇到一个seg错误。我已经尝试在其上运行GDB,我收到以下错误:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a60a03 in _IO_vfprintf_internal (s=<optimized out>,     format=<optimized out>, 
ap=<optimized out>) at vfprintf.c:1661
1661    vfprintf.c: No such file or directory.

至于我如何接受这个数据我有6个scanf()函数,它们接受struct的6个特性,将它们存储到一个临时变量,malloc为每个字符串,malloc一个新的car struct调用newCar,并将struct中的每个变量设置为其临时变量。如果它是第一个车辆入口,那么carInventory等于newCar。添加另一辆汽车时,会发生相同的过程,除非while循环沿着名为newCarInventory的新结构移动,并使用carInventory存储来自memcpy()的数据。以下是我正在使用的实际代码:

void addRecord(){

newCar = (struct car *) malloc(sizeof(struct car)); //Allocates memory for a car entry

int i;
int inventoryAmountTemp = inventoryAmount; //Grabs the global value and stores it to a local variable

//Local variables used to hold onto inputted values
char make[25];
char model[25];
int year;
int mpg;
int mileage;
int cost;

printf("\nMake: ");
scanf("%s", &make);
printf("\nModel: ");
scanf("%s", &model);
printf("\nYear: ");
scanf("%i", &year);
printf("\nMiles Per Gallon: ");
scanf("%i", &mpg);
printf("\nMileage: ");
scanf("%i", &mileage);
printf("\nCost: ");
scanf("%i", &cost);

newCar->make = (char *)malloc(strlen(make)+2); //Allocates memory for string
newCar->model = (char *)malloc(strlen(model)+2);
strcpy(newCar->make, make); //Coppies string into newCar
strcpy(newCar->model, model);
newCar->year = year;
newCar->mpg = mpg;
newCar->mileage = mileage;
newCar->cost = cost;

if(inventoryAmountTemp == 0){
    carInventory = newCar;
}
else{
    newCarInventory = (struct car *) malloc(inventoryAmountTemp * sizeof(struct car)); //Memory made for a new Car Inventory.
    headPtr = carInventory;
    headPtr2 = newCarInventory;
    tailPtr = newCar;

    i = 0;
    while(i <= inventoryAmountTemp){
        memcpy(&(newCarInventory->make), &(headPtr->make), sizeof(headPtr->make));
        memcpy(&(newCarInventory->model), &(headPtr->model), sizeof(headPtr->model)); 
        memcpy(&(newCarInventory->year), &(headPtr->year), sizeof(headPtr->year));
        memcpy(&(newCarInventory->mpg), &(headPtr->mpg), sizeof(headPtr->mpg));
        memcpy(&(newCarInventory->mileage), &(headPtr->mileage), sizeof(headPtr->mileage));
        memcpy(&(newCarInventory->cost), &(headPtr->cost), sizeof(headPtr->cost));

        i++;
        if(i < inventoryAmountTemp && i != inventoryAmountTemp){
            headPtr++;
            newCarInventory++;
        }
        else if(i == inventoryAmountTemp){
            headPtr = tailPtr;
            newCarInventory++;
        }

    }

    newCarInventory = headPtr2;
    carInventory = newCarInventory;
}

inventoryAmountTemp += 1;
accessTemp += 1;
access = accessTemp;
inventoryAmount = inventoryAmountTemp;
}

我知道这个问题存在于这个函数中,因为我有fprintf()语句(我在这段代码中用过)来测试每一步。那些失败的是那些在while循环中的循环,当循环第二次进入第三次汽车入口时。

任何指导都会非常感激!

2 个答案:

答案 0 :(得分:0)

尝试在gdb中使用backtrace来查看分段错误的来源

答案 1 :(得分:0)

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

struct car{
    char *make;
    char *model;
    int year;
    int mpg;
    int mileage;
    int cost;
};
int inventoryAmount=0;
struct car* CarList=0;


char *copyString(char *str){
    char *buff=0;
    if(str){
        int l=strlen(str);
        buff=malloc(l+1);
        if(buff){
            for(int i=0;i<=l;i++)
                buff[i]=str[i];
        }

    }
    return buff;
}

/*_______________________________________________________
*/

void propmt(const char *msg,const char*fmt,void *output){
    printf("\n%s: ",msg);
    scanf(fmt,output);
    return;
}
/*_______________________________________________________
*/
void addRecord(void){


    struct car *newCar ;

    //Local variables used to hold onto inputted values
    char make[25];
    char model[25];
    int year;
    int mpg;
    int mileage;
    int cost;


    if(CarList){
        newCar=  realloc(CarList,sizeof(struct car)*(inventoryAmount+1)); 

    }else{
        newCar=  malloc(sizeof(struct car));

    }

    if(!newCar){
        printf("Failed to allocate new car\n");
        exit(1);
    }
    CarList=newCar;
    newCar=&newCar[inventoryAmount];
    inventoryAmount++;


    propmt("Make","%s", &make);
    propmt("Model","%s", &model);
    propmt("Year","%i", &year);
    propmt("Miles Per Gallon","%i", &mpg);
    propmt("Mileage","%i", &mileage);
    propmt("Cost","%i", &cost);


    newCar->make=copyString( make); //Coppies string into newCar
    newCar->model=copyString( model);
    newCar->year = year;
    newCar->mpg = mpg;
    newCar->mileage = mileage;
    newCar->cost = cost;

    return;
}

/*_______________________________________________________
*/

void listCars(void){
    int i;
    if(!inventoryAmount){
        printf("\nNo cars in inventory\n");
        return;
    }
    for(i=0;i<inventoryAmount;i++){
        printf("Make: %s\n"             ,CarList[i].make);
        printf("Model:%s\n"             ,CarList[i].model);
        printf("Year:%i\n"              ,CarList[i].year);
        printf("Miles Per Gallon:%i\n"  ,CarList[i].mpg);
        printf("Mileage:%i\n"           ,CarList[i].mileage);
        printf("Cost:%i\n"              ,CarList[i].cost);
        printf("======================================\n");
    }
    return;
}
void pause(void){
    printf("Press a key to continue");
    _getch();
    printf("\n");
}
int main(void){
    int q;
    for(;;){
        _clrscr();
        printf(
            "1 - List cars\n"
            "2 - Add new car\n"
            "0 - Exit program\n");
        scanf("%i",&q);
        switch(q){
            case 1:
                listCars();
                pause();
                break;
            case 2:
                addRecord();
                pause();
                break;
            case 0:
                return 0;
                break;
        }

    }

    return 0;
}

使用mallocrealloc

的好样本