我有一個將檔案中的行復制到字串陣列中的作業示例。我想移動代碼以將行復制到一個函式中,我只需向該函式傳遞一個指向字串陣列的指標,其中將存盤行,以及一個指向檔案的指標。但是,我試圖將代碼移動到一個函式中并不斷出現段錯誤。我嘗試使用 GDB 進行除錯,似乎問題出在記憶體分配到rows. 但我無法弄清楚問題是什么。realloc 似乎作業正常,因為我發現第三次迭代時行的大小增加(使用 malloc_usable_size(*rows)),但隨后出現段錯誤。我gcc -Wall -Wextra -pedantic -std=c99 -g c_programs/read_file_function.c在 Linux 上編譯。
作業示例
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Please supply a file path:\n%s <file path>\n", argv[0]);
return EXIT_FAILURE;
}
FILE *fp = fopen(argv[1], "r");
if (!fp)
{
perror("ERROR");
return EXIT_FAILURE;
}
char **rows = (char **)malloc(sizeof(char *));
char *lineBuf = NULL;
size_t n = 0;
size_t nLines = 0;
ssize_t lineLength = 0;
size_t i = 0;
while ((lineLength = getline(&lineBuf, &n, fp)) != -1)
{
lineBuf[strcspn(lineBuf, "\n")] = 0;
lineBuf[strcspn(lineBuf, "\r")] = 0;
rows[i] = (char *)malloc(lineLength 1);
strcpy(rows[i], lineBuf);
i ;
nLines = i;
rows = (char **)realloc(rows, (nLines 1) * sizeof(char *));
}
printf("nLines: %lu\n", nLines);
printf("row 1: %s\n", rows[0]);
printf("row 2: %s\n", rows[1]);
printf("row 2: %s\n", rows[10]);
return 0;
}
非作業功能版本
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t readFile(FILE **fp, char ***rows)
{
char *lineBuf = NULL;
size_t n = 0;
size_t nLines = 0;
ssize_t lineLength = 0;
size_t i = 0;
while ((lineLength = getline(&lineBuf, &n, *fp)) != -1)
{
lineBuf[strcspn(lineBuf, "\n")] = 0;
lineBuf[strcspn(lineBuf, "\r")] = 0;
*rows[i] = (char *)malloc(lineLength 1);
strcpy(*rows[i], lineBuf);
i ;
nLines = i;
*rows = (char **)realloc(*rows, (nLines 1) * sizeof(char *));
}
return nLines;
}
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Please supply a file path:\n%s <file path>\n", argv[0]);
return EXIT_FAILURE;
}
FILE *fp = fopen(argv[1], "r");
if (!fp)
{
perror("ERROR");
return EXIT_FAILURE;
}
char **rows = (char **)malloc(sizeof(char *));
size_t nLines = readFile(&fp, &rows);
printf("nLines: %lu", nLines);
printf("row 1: %s", rows[0]);
printf("row 2: %s", rows[1]);
return 0;
}
uj5u.com熱心網友回復:
*rows[i]正在做*(rows[i])- 訪問i行陣列中的第 th 個元素,然后取消參考它。你想要做(*rows)[i]- 取消參考rows然后訪問ith 元素。
我建議:
readFile(..., char ***rows0) {
char **rows = NULL; // temporary internal variable
...
// use rows normally
rows = stuff();
...
// when finished, assign once
*rows0 = rows;
return nLines;
}
但不要成為三星級程式員。充其量,使用一個結構,->是易于使用的。喜歡:
struct string {
char *str;
};
struct lines {
struct string *strs;
size_t cnt;
};
// @return 0 on success, otherwise error
int readFile(...., struct lines *p) {
// initialization
p->cnt = 0;
p->strs = NULL;
...
void *pnt = realloc(p->strs, (p->cnt 1) * ....);
if (!pnt) { /* handle error */ return -1; }
p->strs = pnt;
p->strs[p->cnt]->str = malloc(lineLenght 1);
if (!p->strs[p->cnt]->str) { /* handle error */ return -2; }
strcpy(p->strs[p->cnt]->str, lineBuf);
p->cnt ;
...
return 0; /* success */
}
int main(int argc, char **argv) {
struct lines p = {0};
if (readFile(..., &p)) {
/* handle error */
}
printf("nLines: %zu\n", p.cnt);
不要預先分配記憶體。使用記憶體初始化記憶體NULL并realloc 在使用記憶體之前呼叫。realloc(NULL與 相同malloc()。
檢查分配錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/341251.html
上一篇:Axios不POSTing陣列
下一篇:查找亂數的MAX和MIN
