그래서 내 가정용 컴퓨터에서 잘 컴파일되는이 프로그램을 가지고 있지만, 대학 서버에서 컴파일하자마자 깨집니다. :/내 엉덩이에 엄청난 고통이 있습니다. 나는 어디서 또는 무엇이 오류를 일으키는지도 모른다. 대학에서 제기 한 valgrind 보고서로 처음 시작됩니다. 왜이 segfaulting 무엇입니까? 누군가 valgrind 오류를 설명 할 수 있습니까?
==13527== Memcheck, a memory error detector
==13527== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==13527== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==13527== Command: ./main stock.dat coins.dat
==13527==
==13527== Invalid write of size 8
==13527== at 0x402762: load_data (in /RMIThome/shr/5/s3234575/Assignments2/main)
==13527== by 0x4028BE: main (in /RMIThome/shr/5/s3234575/Assignments2/main)
==13527== Address 0x6172676f72502074 is not stack'd, malloc'd or (recently) free'd
==13527==
==13527==
==13527== Process terminating with default action of signal 11 (SIGSEGV)
==13527== General Protection Fault
==13527== at 0x402762: load_data (in /RMIThome/shr/5/s3234575/Assignments2/main)
==13527== by 0x4028BE: main (in /RMIThome/shr/5/s3234575/Assignments2/main)
==13527==
==13527== HEAP SUMMARY:
==13527== in use at exit: 4,096 bytes in 19 blocks
==13527== total heap usage: 19 allocs, 0 frees, 4,096 bytes allocated
==13527==
==13527== LEAK SUMMARY:
==13527== definitely lost: 1,868 bytes in 8 blocks
==13527== indirectly lost: 0 bytes in 0 blocks
==13527== possibly lost: 0 bytes in 0 blocks
==13527== still reachable: 2,228 bytes in 11 blocks
==13527== suppressed: 0 bytes in 0 blocks
==13527== Rerun with --leak-check=full to see details of leaked memory
==13527==
==13527== For counts of detected and suppressed errors, rerun with: -v
==13527== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
그래서 오류는 주요 발생 말하고있다? 하지만 그것은 load_data 함수에 도달 할 때까지 표시되지 않습니까? 또는 main에서 호출되는 load_data에서 오류가 발생합니까?
다음 코드는 main입니다.
#define _GNU_SOURCE
#include "assert.h"
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vm_menu.h"
#include "vm_utility.h"
#include "vm_options.h"
#include "vm_type.h"
#define NUMARGS 3
struct menu_item * displayMenu(struct menu_item * menu, struct vm * vendMachine);
int main(int argc, char * argv[])
{
struct vm *vm;
vm = malloc(sizeof(struct vm));
struct vm *vend;
vend = malloc(sizeof(struct vm));
struct menu_item menu_items[NUM_MENU_ITEMS];
/*check if there are at least 3 arguments being passed through the command line */
if(argc!=3)
{
printf("Insuffcient arguments \n");
return EXIT_SUCCESS;
}
menu_init(menu_items);
/* initialise the vm */
vm_init(vm);
load_data(vm, argv[1], argv[2]);
vend->item_list.head = vm->item_list.head;
BOOLEAN RUNNING = TRUE;
while(RUNNING){
vm->item_list.head = vend->item_list.head;
fflush(stdout);
fflush(stdin);
displayMenu(menu_items, vm);
}
read_rest_of_line();
return EXIT_SUCCESS;
}
오류가 구조체에 있다고 생각합니다. menu_item menu_items [NUM_MENU_ITEMS]; 왜냐하면 나는 아무것도 초기화하지 않았기 때문이다. 하지만 malloc을 사용하여 구조체 배열에 메모리를 할당 할 수있는 방법이 확실하지 않습니까?
로드 데이터 파일은;
#include "vm_utility.h"
/* print list */
void print_list(struct vm_node *root) {
while (root) {
printf("%s",root->data->id);
root = root->next;
}
printf("\n");
}
/*creates a item and initialise the values */
struct stock_item* setupNode(char *line) {
struct stock_item *root;
root = malloc(sizeof(struct stock_item));
char *ptr;
char *ptrs;
const char del[2] = "|";
const char delm[2] = ".";
char *prices;
strcpy(root->id, strtok_r(line, del, &ptr)); // returns the ID and stores in in the root node.
strcpy(root->name, strtok_r(NULL, del, &ptr)); // returns the description and stores it in the root node.
strcpy(root->description, strtok_r(NULL, del, &ptr)); // returns the description and stores it in the root node.
prices = strtok_r(NULL, del, &ptr); // returns a string of the price for vm_item.
char *dols = strtok(prices, delm);
char *cents = strtok(NULL, delm);
long int dol = strtol(dols,&ptrs,10);
long int cent = strtol(cents, NULL, 10);
root->price.dollars = dol;
root->price.cents = cent;
int quantity = strtol(strtok_r(NULL, del, &ptr), NULL, 10); // returns how many items are in stock.
root->on_hand = quantity;
return root;
}
/*creates the list within the vm->item_list*/
int addNodeBottom(char *val, struct vm_node *head){
//create new node
struct stock_item *data;
data = malloc(sizeof(struct stock_item));
data = setupNode(val);
if (head->data == NULL)
head->data = data;
else
{
struct vm_node *current = NULL;
for (current = head; current->next != NULL; current = current->next)
;
current->next = malloc(sizeof(*current->next));
current->next->data = data;
current->next->next = NULL;
}
return 0;
}
/*creates coin array stores in vm->coins; */
struct coin * addCoins(char *val){
char *ptr =NULL;
char *ptrs =NULL;
const char *deli = ",";
char *denominations = strtok_r(val, deli, &ptrs);
char *counts = strtok_r(NULL, deli, &ptrs);
long int denomination = strtol(denominations, &ptr,10);
long int count = strtol(counts,NULL, 10);
struct coin *k;
k = malloc(sizeof(struct coin));
k->denom = denomination;
k->count = count;
return k;
}
/*
* Clears the input buffer.
* */
void read_rest_of_line(void)
{
int ch;
while(ch = getc(stdin), ch!='\n' && ch != EOF)
;
clearerr(stdin);
}
/*
* Initialises the vm data structure declared in main to safe initial
* values.
* */
BOOLEAN vm_init(struct vm * vm)
{
struct vm_node * vmNode;
vmNode = malloc(sizeof(struct vm_node));
vmNode->next = NULL;
vmNode->data = NULL;
vm->item_list.head = NULL;
vm->coinsfile = NULL;
vm->foodfile = NULL;
return FALSE;
}
/*
* Loads data from the .dat files into memory.
* */
BOOLEAN load_data(struct vm * vm, const char * item_fname,
const char * coins_fname){
FILE *file;
file = fopen(item_fname, "r+");
char buf[256];
struct vm_node *vmNodes;
vmNodes = malloc(sizeof(struct vm_node));
vmNodes->data = NULL;
vmNodes->next = NULL;
while (fgets(buf, sizeof buf, file) != NULL) {
addNodeBottom(buf,vmNodes);
}
vm->item_list.head = vmNodes;
fclose(file);
/*now open coin file*/
FILE *fileCoin;
fileCoin = fopen(coins_fname, "r+");
char bufCoin[256];
int i = 0;
//vmNode->next = NULL;
struct coin *j;
while (fgets(bufCoin, sizeof bufCoin, fileCoin) != NULL) {
j = addCoins(bufCoin);
vm->coins[i] = *j;
free(j);
i++;
}
/**/
/* Test reason for reaching NULL. */
fclose(fileCoin);
return FALSE;
}
/*
* Frees all dynamically allocated data.
* */
void system_free(struct vm * vm)
{
/* The UNUSED() function is designed to prevent warnings while your
* code is only partially complete. Delete this function call once
* you are using vm in your own code */
}
또한 모든 구조체에 대해 typedef를 쉽게 공유 할 수있게합니다. 집에서
typedef enum truefalse
{
FALSE, TRUE
} BOOLEAN;
/* Each price will have a dollars and a cents component */
struct price
{
unsigned dollars,cents;
};
/* The different denominations of coins available */
enum denomination
{
FIVE_CENTS, TEN_CENTS, TWENTY_CENTS, FIFTY_CENTS, ONE_DOLLAR,
TWO_DOLLARS, FIVE_DOLLARS, TEN_DOLLARS
};
/* Each coin in the coins array will have a denomination (20 cents,
* 50 cents, etc) and a count - how many of that coin do we have on hand
*/
struct coin
{
enum denomination denom;
unsigned count;
};
/* The data structure that holds the data for each item of stock
*/
struct stock_item
{
char id[IDLEN+1];
char name[NAMELEN+1];
char description[DESCLEN+1];
struct price price;
unsigned on_hand;
};
/* The data structure that holds a pointer to the stock_item data and a
* pointer to the next node in the list
*/
struct vm_node
{
struct stock_item * data;
struct vm_node * next;
};
/* The head of the list - has a pointer to the rest of the list and a
* stores the length of the list
*/
struct vm_list
{
struct vm_node * head;
unsigned length;
};
/* This is the head of our overall data structure. We have a pointer to
* the vending machine list as well as an array of coins.
*/
struct vm
{
struct vm_list item_list;
struct coin coins[NUMDENOMS];
char * foodfile;
char * coinsfile;
};
Valgrind의는 :
==9814== Memcheck, a memory error detector
==9814== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9814== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9814== Command: ./main stock.dat coins.dat
==9814==
Main Menu:
1. Display Items
2. Purchase Items
3. Save and Exit
Administrator-Only Menu:
4. Add Item
5. Remove Item
6. Display Coins
7. Reset Stock
8. Reset Coins
9. Abort Program
Select your option (1-9):
가정에서 프로그램에서 valgrind를 실행 해보십시오. –
@JimBalter 이것은 집에서 실행할 때 얻을 수있는 것입니다. (== 9814 == Memcheck, 메모리 오류 감지기 == 9814 == Copyright (C) 2002-2013 및 GNU GPL'd 줄리안 스워드 등 == Valgrind의-3.10.0.SVN 및 LibVEX를 사용하여 9814 ==, 저작권 정보 -h와 다시 실행 == 9814 == 명령 :. coins.dat ./main stock.dat == 9814 == 주 메뉴 : \t 1. 표시 항목 \t 2. 구매 항목 \t 3. 저장하고 종료 관리자 전용 메뉴 : \t 4. 항목 추가 \t 5. 제거 항목 \t 6. 디스플레이 동전 \t 7. 재설정 재고 \t 8.리셋 동전을 \t 9 중단 프로그램 은 옵션 (1-9)를 선택 : 디버그 정보 (전체 경고)와 –
컴파일을하고 문제를 파악하기 위해 디버거에서 프로그램을 실행합니다. (오류는 load_data에서 발생하지만 반드시 버그가 있음을 의미하지는 않습니다.) – Mat