StackOverflow への最初の投稿 (トレード テスターであり、空き時間には非常に下手なプログラマー)。開示目的のために、これは私が苦労している大学の課題です (私が知る限り、ここで質問することは禁止されていません.
とにかく、テキスト ファイルから行を読み取り、行データをトークン化し、リンク リストを作成してから、各トークン (2 つの文字列、1 つの浮動小数点数、1 つの符号なし) をノードに挿入するプログラムがあります。ノードによって使用されているメモリが解放されるまで、すべて問題ありません。プログラム全体がクラッシュします。デバッグ後、問題を 2 つの文字列コピー操作に切り分けたようです。どちらも完全に有効に見えますが、 free() はまったく好きではありません。strncpy() を試しました - 違いはありません。文字列 char を char ごとにコピーしようとしました - 違いはありません。今、私は途方に暮れています...
誰かが見たい場合は、以下のコード (ああ、さらに開示 - ほとんど完全な C n00b です。そうです。下に悪い慣行が見られる場合、それは私です...)
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "ts.h"
int main(void)
{
/* Variables */
FILE *stream;
char buf[BUFSIZ];
/* Open stock file */ //TODO - make this dynamic, don't hard-code file name
stream = fopen("stock.csv", "r");
assert(stream);
/* Using addStockNode */
while (fgets(buf, BUFSIZ, stream))
{
addStockNode(buf);
}
}
void addStockNode(char* stockLine)
{
//Create linked list
StockNodePtr head, new, current, previous, nextStock;
unsigned listSize;
char *stkTok1, *stkTok2, *stkTok3, *stkTok4;
unsigned stkLevel;
int i;
float stkPrice;
listSize = 0;
head = NULL;
/* Create new stock node */
if ((new = malloc(sizeof(StockNodePtr))) == NULL)
{
fprintf(stderr,"\nMemory allocation for node insertion failed\n");
fprintf(stderr,"Aborting\n");
exit(EXIT_FAILURE);
}
/* Tokenise data */
stkTok1 = strtok(stockLine, ",");
stkTok2 = strtok(NULL, ",");
stkTok3 = strtok(NULL, ",");
stkTok4 = strtok(NULL, ",");
/* Search to find where in insert new list node */ //TODO - needs to be adapted to sort by stock DESCRIPTION
current = head;
previous = NULL;
/* stockID */
// strcpy(new->stockID, stkTok1); //falls over at free()
// strncpy(new->stockID, stkTok1, STOCKID_LEN); //falls over at free()
for(i = 0; i < strlen(stkTok1); i++) //still falls over at free()
{
new->stockID[i] = stkTok1[i];
}
/* description */
// strcpy(new->description, stkTok2); //falls over at free()
/* unitPrice */
stkPrice = strtof(stkTok3, NULL);
new->unitPrice = stkPrice;
/* StockLevel */
stkLevel = strtol(stkTok4, NULL, 10);
new->stockLevel = stkLevel;
/*nextStock */
new->nextStock = current;
/* Increment listSize */
listSize++;
//TAKE OUT LATER - loadData can iterate through each line of the file */
if(previous == NULL)
{
head = new;
}
else
{
previous->nextStock = new;
}
/* Print node details */
current = head;
printf("%s,%s,%f,%i\n", current->stockID, current->description, current->unitPrice, current->stockLevel);
/* Deallocate memory used by node */
current = head;
while(current != NULL)
{
nextStock = current->nextStock;
free(current); //EXECUTE THIS, IT FALLS OVER (with strcpy lines uncommented)
current = nextStock;
}
return EXIT_SUCCESS;
}*
完全を期すために、ここにストックノード構造体があります...
typedef struct stockNode
{
char stockID[STOCKID_LEN + 1];
char description[DESCRIPTION_MAX + 1];
float unitPrice;
unsigned stockLevel;
StockNodePtr nextStock;
} StockNodeType;
誰かが私が間違っているところを指摘できるなら、私はそれを感謝します!
編集 - ストックノード定数は次のとおりです...
#define STOCKID_LEN 5
#define DESCRIPTION_MAX 40
#define PRICE_COLWIDTH 7
#define STOCKLEVEL_COLWIDTH 3
#define STOCKLEVEL_MAX 100
あ、それと、追加された在庫データ(別に問題ないですけど)…
S0001,Slazenger Classic Racquet,150.00,5
S0002,Slazenger Lite Racquet,98.00,3
S0003,Wilson Tournament Gold Balls,14.95,20
S0004,Dunlop Grand Prix Balls,10.95,25
S0005,Luft Nemesis Racquet,125.00,1
S0006,Wilson Tournament Balls,12.95,12