C语言中如何将Token指向的字符串存入数组?CSV转二维数组遇segfault
Let's break down your questions and the segfault issue step by step, like we would in a real Stack Overflow thread:
1. Are there errors in my variable definitions?
Segfaults that pop up when storing data (but not when printing) almost always tie to memory mismanagement in your array setup. Here are the most common mistakes:
- Uninitialized pointer arrays: If you declared something like
char** csv_data;but never allocated memory for the rows (e.g.,csv_data = malloc(num_rows * sizeof(char*));), trying to assigncsv_data[row] = my_string;writes to a random, invalid memory address—boom, segfault. - Fixed-size array overflow: If you used a static 2D char array (e.g.,
char csv_data[100][100];) but your CSV fields are longer than 99 characters, you'll overflow the buffer. Printing might work temporarily, but storing the data corrupts memory and triggers a crash later. - Missing null checks: If you used
mallocorstrdupbut didn't verify they returned a valid pointer, you could be writing toNULLif allocation fails.
Example of a safe dynamic 2D string array setup:
// Assume you've already parsed the CSV to get row/column counts int num_rows = 5; int num_cols = 3; char** csv_data = malloc(num_rows * sizeof(char*)); if (!csv_data) { /* handle allocation failure (e.g., exit with error) */ } for (int i = 0; i < num_rows; i++) { // Allocate space for each row's fields (adjust MAX_FIELD_LENGTH as needed) csv_data[i] = malloc((MAX_FIELD_LENGTH + 1) * sizeof(char)); if (!csv_data[i]) { /* clean up previously allocated memory and exit */ } }
2. What's the purpose of storing pointers in an array, and how does it help with string data?
Storing char* pointers in an array is the standard way to handle variable-length string data in a 2D structure—here's why it's useful:
- Flexibility: CSV fields rarely have uniform lengths. A pointer array lets you allocate exactly the right amount of memory for each string (instead of wasting space with a one-size-fits-all char array). For example, a field like "USA" only needs 4 bytes, while a field like "123-456-7890" needs 13—pointers eliminate the need to predefine a huge maximum length.
- Memory efficiency: You don't have to reserve space for the longest possible field for every entry, which saves memory for shorter strings.
Where you're probably messing up:
- If you're storing the raw pointer returned by
strtok, remember thatstrtokmodifies the original input buffer and returns pointers to that buffer. If you overwrite the buffer (e.g., by reading the next CSV line), those pointers will point to garbage data. Instead, usestrdupto copy the string into fresh memory before storing the pointer:char* token = strtok(line, ","); csv_data[row][col] = strdup(token); // Store a copy, not the temporary buffer pointer - If you're trying to assign string literals (like
"hello") to the array and then modify them, that's undefined behavior—string literals live in read-only memory, so writing to them will crash your program.
Bonus: Why you can print data but can't store it
The most likely scenario here is that you're printing directly from a temporary buffer (like the line you read with fgets) while it's still valid, but storing pointers to that same buffer. Once the buffer is overwritten or freed, those pointers reference invalid memory, causing the segfault when you try to access the array later.
内容的提问来源于stack exchange,提问作者Emre Utku Solak

