gpt4 book ai didi

c - 为什么会出现段错误?有人可以解释 valgrind 错误吗?

转载 作者:行者123 更新时间:2023-11-30 21:41:24 29 4
gpt4 key购买 nike

所以我有这个程序,可以在我的家用机器上编译得很好,但是一旦我在大学服务器上编译它,它就会崩溃......:/这对我来说是一个巨大的痛苦。我不知道在哪里或什么可能导致错误。我首先从大学的 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)

所以错误说它发生在 main 中?但直到到达load_data函数才显示,或者是在main中调用的load_data中发生错误?

以下代码是主要代码。

#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;
}

我认为错误出现在 struct 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 表示非法写入发生在地址 0x6172676f72502074

如果将该地址视为 ASCII 字符,则为:argorP t,或者从小端转换为:t Progra

这看起来像是菜单项之一“9. 中止程序”的一部分。也许错误是 menu_init() 写入到了 menu_items[] 数组的末尾?

我猜想在调试器中单步调试你的程序应该足够快地找到问题。

关于c - 为什么会出现段错误?有人可以解释 valgrind 错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26437196/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com