C语言 进程返回 -1073741819 (0xc0000005) Code::Blocks
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15768355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Process Returned -1073741819 (0xc0000005) Code::Blocks
提问by Nick
I'm kind of new to programming C with Code::Blocks(Version 12.11), started this semester in my college, but I manage.
我对使用 Code::Blocks(版本 12.11)编程 C 有点陌生,我这学期从我的大学开始,但我能做到。
I recently learned in class about pointers, memory allocation and dynamic arrays(none are my forte), and I incorporated them in my program(and it compiles)
我最近在课堂上学习了指针、内存分配和动态数组(没有一个是我的强项),我将它们合并到我的程序中(并编译)
Now the problem comes when I run the Program and go to Menu -> Add a Product, the program terminates when I input a price and I receive "Process Returned -1073741819 (0xc0000005)". I did some research and found out it's an access violation but I don't really understand how to correct it.
现在,当我运行程序并转到菜单 -> 添加产品时,问题出现了,当我输入价格并收到“流程返回 -1073741819 (0xc0000005)”时,程序终止。我做了一些研究,发现这是一个访问冲突,但我真的不明白如何纠正它。
Regards
问候
Here's the code:
这是代码:
#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;
}
}
回答by hmjd
An attempt is being made to write to randon memory, via the uninitialized pointer tempIdCode:
正在尝试通过未初始化的指针写入随机内存tempIdCode:
char* inputIdCode(){
char* tempIdCode;
puts("ID Code?");
scanf("%s", tempIdCode);
system("cls");
return tempIdCode;
}
You need to allocate memory for tempIdCodebefore attempting to write to it. You must use malloc()here (and not return the address of a local array):
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);
}
The caller of the function must explicitly check for a return NULLpointer. The caller must also free()the allocated memory.
函数的调用者必须显式检查返回NULL指针。调用者还必须free()分配内存。
回答by alk
This is a killer:
这是一个杀手:
// Input Product Name
char *inputProductName(int length){
char name[maxCharName];
puts("Product Name?");
scanf("%s", name); fflush(stdin);
system("cls");
return name;
}
The reference returned by this function points to an already freed block of memory on the stack, as char nameis only valid as long the program is inside the function nameis declared in.
此函数返回的引用指向堆栈上已释放的内存块,char name只有在程序在函数内部name声明时才有效。
When leaving the function nameis freed automagically, so any dereferencing of the function's result leads to UB, as it most propably will be accessing unallocated memory.
离开函数时name会自动释放,因此对函数结果的任何取消引用都会导致 UB,因为它很可能会访问未分配的内存。
To solve this you might like to pass in a buffer, where to read the data into:
为了解决这个问题,您可能希望传入一个缓冲区,将数据读入:
// Input Product Name
char * inputProductName(int length, char * name){
puts("Product Name?");
scanf("%s", name); fflush(stdin);
system("cls");
return name;
}
and call it like this:
并这样称呼它:
// 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);
...

