3

我对使用 Code::Blocks(版本 12.11)进行 C 编程有点陌生,这学期从我的大学开始,但我做到了。

我最近在课堂上学习了指针、内存分配和动态数组(没有一个是我的强项),并将它们合并到我的程序中(并且它可以编译)

现在问题来了,当我运行程序并转到菜单 - > 添加产品时,程序在我输入价格时终止,我收到“进程返回 -1073741819 (0xc0000005)”。我做了一些研究,发现这是访问冲突,但我真的不明白如何纠正它。

问候

这是代码:

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

#define maxCharName 64
#define maxCharUserPass 8
#define maxCharId 5

// Product Structure
typedef struct{
    char name[maxCharName];
    char idCode[maxCharId];
    float price;
    float stock;
}product;

// DataBase of Products
typedef struct{
    int sizeT;
    product *array;
} TProducts;

TProducts a;


// Press any Key on the Keyboard to Proceed
void pressKeyToContinue(){
    puts("\n\n\n     Please Press any Key to Continue...");
    getchar();
}

// Start Page
void startPage(){
    puts("\n\n\n                      -- Welcome to WeePro Manager --\n\n");
    puts("                             -- Version 1.0 --\n\n\n\n");
    puts("                    -- Developped By: Nick --");

    pressKeyToContinue();
    system("cls");
    }

// Program Terminator
void shutdown(){
    puts("\n\n\n      Good-Bye");
    pressKeyToContinue();               // Awaits User Input
    exit(0);
}

// Asks User Information for Verification
int userLogin(){
    char userName[maxCharUserPass] = "WPuser";
    char inputUserName[maxCharUserPass];

    char passWord[maxCharUserPass] = "12345";
    char inputPassWord[maxCharUserPass];

    printf("Username?     ");
    scanf("%s",inputUserName); fflush(stdin);

    printf("Password?     ");
    scanf("%s", inputPassWord); fflush(stdin);

    system("cls");

    if((strcmp(userName, inputUserName) == 0)&&(strcmp(passWord, inputPassWord) == 0)){
        return 1;
    }else{ return 0;}
}

// Lists All Products With their Respective Information
void listAll(){
    int idx = 0;
    puts("List:");
    while((idx < a.sizeT)&&(a.array[idx].name != NULL)){
        printf(":::%s ( id: %s )", a.array[idx].name, a.array[idx].idCode);
        printf("Price: %6.2f eur/g", a.array[idx].price);
        printf("Stock: %6.2f g", a.array[idx].stock);

        idx++;
    }

    pressKeyToContinue();
    system("cls");
}

// Input Product ID Code
char* inputIdCode(){
    char* tempIdCode;
    puts("ID Code?");
    scanf("%s", tempIdCode);

    system("cls");
    return tempIdCode;
}

// Search By ID Code
int searchIdCode(){
    int idx = 0;
    char* tempIdCode;
    tempIdCode = inputIdCode();
    do{
        if(strcmp(a.array[idx].idCode, tempIdCode) == 0){
            return idx;
        }else{
            idx++;
        }
    }while(idx < a.sizeT);

    puts("No Product With Such an ID Code!");
    return -1;
}



// Input Product Name
char *inputProductName(int length){
    char name[maxCharName];

    puts("Product Name?");
    scanf("%s", name); fflush(stdin);

    system("cls");
    return name;
}

// Input Product Price
float inputProductPrice(int length){
    float price;

    puts("Product Price?");
    scanf("%f", price); fflush(stdin);

    system("cls");
    return price;
}

// Input Product Stock
float inputProductQuantity(int length){
    float quantity;

    puts("Product Stock?");
    scanf("%f", quantity); fflush(stdin);

    system("cls");
    return quantity;
}


/////////////////
// Add Product //
/////////////////

// New Product Adder
void addProduct(){
    char* tempStr;
    float temp;

    if(a.sizeT == 0){
        a.sizeT = 1;
        a.array = (product*)malloc((a.sizeT)*sizeof(product));
    }else{
        a.sizeT++;
        a.array = (product*)realloc(a.array, (a.sizeT)*sizeof(product));
    }

    tempStr = inputProductName(a.sizeT);
    strcpy(a.array[a.sizeT].name, tempStr);
    temp = inputProductPrice(a.sizeT);
    temp = inputProductQuantity(a.sizeT);

    system("cls");
}

void transaction(){}


////////////////////
// Delete Product //
////////////////////

// Delete Product
void deleteProduct(){
    int idx, idxPro;
    char* tempIdCode;

    puts("Delete Which Product?\n");
    tempIdCode = inputIdCode();
    idxPro = searchIdCode(tempIdCode);

    idx = idxPro + 1;
    while(idx < a.sizeT){
        a.array[idx] = a.array[idx+1];
        idx++;
    }
    a.array = realloc(a.array, (a.sizeT-1)*sizeof(product));
}

//Product Information Modifier
void modifyProduct(){
    char choice;
    int tabLength;
    do{
        puts("Modify What?\n");
        puts("   -> [N]ame\n");
        puts("   -> [P]rice\n");
        puts("   -> [S]tock\n\n");
        puts("   -> [R]eturn to Previous Menu");                    // Prints the Menus' Options

        scanf("%c", &choice);
        choice = toupper(choice);                               // Save Users' Choice And Up Case
        fflush(stdin);

        switch(choice){
            case 'N':
                    system("cls");
                    tabLength = searchIdCode();
                    inputProductName(tabLength);
                    break;
            case 'P':
                    system("cls");
                    tabLength = searchIdCode();
                    inputProductPrice(tabLength);
                    break;
            case 'S':
                    system("cls");
                    tabLength = searchIdCode();
                    inputProductQuantity(tabLength);
                    break;
            case 'R':
                    system("cls");
                    returnToMenu2();
                    break;
            default:
                puts("Something Went Wrong!\n");
                pressKeyToContinue();
                system("cls");
        }

    }while(choice != 'o');
}

// Sub-Menu Interface
void menu(){
    char choice;
    do{
        puts("Please Make Your Selection.\n");
        puts("   -> [A]dd a New Product\n");
        puts("   -> [M]odify a Product\n");
        puts("   -> [D]elete a Product\n\n");
        puts("   -> [R]eturn to Main Menu");                    // Prints the Menus' Options

        scanf("%c", &choice); fflush(stdin);
        choice = toupper(choice);                               // Save Users' Choice And Up Case

        switch(choice){
            case 'A':
                    system("cls");
                    addProduct();
                    break;
            case 'M':
                    system("cls");
                    modifyProduct();
                    break;
            case 'D':
                    system("cls");
                    deleteProduct();
                    break;
            case 'R':
                    system("cls");
                    returnToMenu1();
                    break;
            default:
                    puts("Something Went Wrong!\n");
                    pressKeyToContinue();
                    system("cls");
        }
    }while(choice != 'o');
}

// Return To Ma

> Blockquote

in Menu
void returnToMenu2(){
    menu();
}

// Main Menu
void controlPanel(){
    char choice;
    do{
        puts("Please Make Your Selection.\n");
        puts("   -> [T]ransaction\n");
        puts("   -> [M]enu\n");
        puts("   -> [L]ist\n");
        puts("   -> [S]hutdown");                                        // Prints the Panels' Options

        scanf("%c", &choice); fflush(stdin);
        choice = toupper(choice);                                   // Save Users' Choice And Up Case

        switch(choice){
            case 'T':
                    system("cls");
                    transaction();
                    break;
            case 'M':
                    system("cls");
                    menu();
                    break;
            case 'L':
                    system("cls");
                    listAll();
                    break;
            case 'S':
                    system("cls");
                    shutdown();
                    break;
            default:
                    puts("Something Went Wrong!\n");
                    pressKeyToContinue();
                    system("cls");
        }
    }while(choice != 'o');
}

// Return To Main Menu
void returnToMenu1(){
    controlPanel();
}


int main(){
    int loginSuccess=1;

    //loginSuccess = userLogin();

    switch(loginSuccess){
    case 0:
        shutdown();
        break;

    case 1:
        startPage();
        controlPanel();
        break;
    }
}
4

2 回答 2

7

正在尝试通过未初始化的指针写入随机内存tempIdCode

char* inputIdCode(){
    char* tempIdCode;
    puts("ID Code?");
    scanf("%s", tempIdCode);

    system("cls");
    return tempIdCode;
}

tempIdCode在尝试写入之前,您需要为其分配内存。您必须malloc()在此处使用(而不是返回本地数组的地址):

char* tempIdCode = malloc(20);
if (tempIdCode)
{
    /* The format specifier "%19s" instructs scanf()
       to read at most 19 characters, one less than
       allocated to allow for terminating null character
       written by scanf(), to prevent potential buffer
       overrun. */
    scanf("%19s", tempIdCode);
}

函数的调用者必须显式检查返回NULL指针。调用者还必须free()分配内存。

于 2013-04-02T15:45:24.860 回答
0

这是一个杀手:

// Input Product Name
char *inputProductName(int length){
  char name[maxCharName];

  puts("Product Name?");
  scanf("%s", name); fflush(stdin);

  system("cls");
  return name;
}

此函数返回的引用指向堆栈上已释放的内存块,char name只有当程序在函数name中声明时才有效。

离开函数时name会自动释放,因此对函数结果的任何取消引用都会导致 UB,因为它很可能会访问未分配的内存。

为了解决这个问题,您可能希望传入一个缓冲区,将数据读入:

// Input Product Name
char * inputProductName(int length, char * name){
  puts("Product Name?");
  scanf("%s", name); fflush(stdin);

  system("cls");
  return name;
}

并这样称呼它:

// New Product Adder
void addProduct(){
  char* tempStr;
  float temp;

  if(a.sizeT == 0){
    a.array = malloc((a.sizeT)*sizeof(product));
  }else{
    a.array = realloc(a.array, (a.sizeT)*sizeof(product));
  }

  a.sizeT++;

  inputProductName(a.sizeT, a.array[a.sizeT].name);

  ...
于 2013-04-02T16:23:53.877 回答