我正在嘗試學習 C 指標傳遞。所以請原諒我的無知。
我想在函式中分配一個二維動態分配的字串陣列。函式簽名是無效的,所以引數是通過參考的。
測驗檔案包含這兩行。
I am testing.
This is not an empty file.
這是我到目前為止所做的。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void read_lines(FILE *fp, char** lines, int *num_lines) {
ssize_t read;
char * line = NULL;
size_t len = 0;
*num_lines = 0;
while ((read = getline(&line, &len, fp)) != -1) {
if (*num_lines == 0) {
// For the first time it holds only one char pointer
*lines = malloc(sizeof(char *));
} else {
// Every time a line is read, space for next pointer is allocated
*lines = realloc(*lines, (*num_lines) * sizeof(char *));
}
// allocate space where the current line can be stored
*(lines (*num_lines)) = malloc(len * sizeof(char));
// Copy data
strcpy(*(lines (*num_lines)), line);
printf("Retrieved line of length %zu:\n", read);
printf("%s\n", line);
(*num_lines) ;
// After first line subsequent lines get truncated if I free
// the storage here, then subsequent lines are not read completely
//if (line) {
// free(line);
//}
}
if (line) {
free(line);
}
}
int main(void)
{
FILE * fp;
char *array;
int num_lines;
fp = fopen("file.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
read_lines(fp, &array, &num_lines);
printf("After returning\n");
// Intend to access as array[0], array[1] etc
// That's not working
// If I access this way then I get seg violation after first line
printf("%s\n", &array[0]);
fclose(fp);
}
我的問題與代碼行內:
- 為什么我不能
line在 while 回圈內釋放存盤空間? - 如何訪問回傳的二維陣列
main?array[0]array[1]似乎不起作用?我想做類似的事情。 - 為什么我現在的做法會產生段錯誤?
更正的代碼將幫助我理解。此外,任何人都可以提供任何很好的參考來為 C 闡明這些概念,我們將不勝感激。
uj5u.com熱心網友回復:
如果free(line)while回圈中,你必須重新設定line到NULL和len到0,下一個呼叫之前getline。否則,getline會認為line是 size 的有效緩沖區len,并可能嘗試寫入它,這實際上是現在所謂的“懸空指標”。
在realloc線條,大小應該是(*num_lines 1) * sizeof(char *),多了一個元素需要被分配給持有剛剛讀線。
和array變數char*,其地址被占用和assiged到引數lines的read_lines。所以,lines是的地址array,而*lines只是array自己。
但
// allocate `char*[1]`
*lines = malloc(sizeof(char *));
和
// allocate `char*[N]` with N=`*num_lines`
*lines = realloc(*lines, (*num_lines) * sizeof(char *));
您將 a 分配char*[]給array,實際上是 a char*。
因此,如果您希望函式按引數回傳字串陣列(即char*[]或char**),則必須使引數成為指向字串陣列(即char***)的指標。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
void read_lines(FILE * fp, char*** lines, int* num_lines) {
ssize_t read;
char* buffer = NULL;
size_t buffer_len = 0;
*num_lines = 0;
while ((read = getline(&buffer, &buffer_len, fp)) != -1) {
// `*lines` is actually `array`,
// modify `*lines` will effectively modify `array`
if (*num_lines == 0) {
// `array` now is `char*[1]`
*lines = (char**)malloc(sizeof(char*)); // A
}
else {
// `array` now is `char*[(*num_lines) 1]`
*lines = (char**)realloc(*lines, (*num_lines 1) * sizeof(char*)); // B
}
// *(x n) is the same as x[n], this line is actually doing:
// `array[*num_lines] = malloc...
*(*lines (*num_lines)) = (char*)malloc((read 1) * sizeof(char)); // C
strcpy(*(*lines (*num_lines)), buffer);
(*num_lines) ;
printf("Retrieved line of length %zu:\n", read);
printf("%s\n", buffer);
}
if (buffer) {
// `line` is `malloc`ed or `realloc`ed by `getline`,
// have to be `free`ed
free(buffer);
}
}
int main(void)
{
FILE* fp;
char** array;
int num_lines;
fp = fopen("file.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
read_lines(fp, &array, &num_lines);
printf("After returning\n");
for (int i = 0; i < *num_lines; i ) {
printf("%s\n", array[i]);
free(array[i]); // corresponding to C
}
free(array); // corresponding to A or B
fclose(fp);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/360372.html
上一篇:如何從指向ACCESS_ALLOWED_ACE結構的指標中的SidStart成員獲取完整的SID?
下一篇:C函式不修改傳遞的陣列
