[英]Seg fault - Incorrect mallocing?
當我嘗試使用這些結構來使用這些 malloc 語句時(這些語句在我的實際代碼中並不是全部排成一行,而是根據需要內置到 mallocs/reallocs 的函數中)我相信我的問題出在這些語句中,所以我只包括那些,因為我相信我目前沒有正確地分配內存,以便讓內存將事物存儲在 data_t 類型結構中的數組 data 中的 word_data_t 結構中,並且在 index_data_t 類型的結構中的數組中:
編輯:添加了可編譯的代碼。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct word_data word_data_t;
typedef struct data data_t;
typedef struct index_data index_data_t;
#define INITIAL_ALLOCATION 2
void test();
struct word_data {
int docunumber;
int freq;
};
struct data {
char *word;
int total_docs;
word_data_t *data;
};
struct index_data {
data_t *index_data_array;
};
int main(int argc, char const *argv[]) {
test();
return 0;
}
void test() {
/* Inside a function called from main */
char entered_word[4] = "wow";
int docunum = 4, index=0, freq=6, current_size_outer_array=0, current_size_inner_array=0;
int total_docs_in=1, doc_freq_pairs=1;
index_data_t *index_data=NULL;
for (index=0; index<4; index++) {
index_data = (index_data_t*)malloc(sizeof(*index_data)*INITIAL_ALLOCATION);
index_data->index_data_array = (data_t*)malloc(sizeof(*index_data->index_data_array)*INITIAL_ALLOCATION);
current_size_outer_array = INITIAL_ALLOCATION;
if (index == 2) {
index_data->index_data_array = realloc(index_data->index_data_array, current_size_outer_array*sizeof(*(index_data->index_data_array)));
}
index_data->index_data_array[index].word=malloc(strlen(entered_word)+1);
index_data->index_data_array[index].word=entered_word;
index_data->index_data_array[index].data = (word_data_t *)malloc(sizeof(word_data_t)*INITIAL_ALLOCATION);
current_size_inner_array = INITIAL_ALLOCATION;
index_data->index_data_array[index].total_docs=total_docs_in;
if (/* Need more data points */ doc_freq_pairs<2) {
index_data->index_data_array[index].data = realloc(index_data->index_data_array[index].data, current_size_inner_array*(sizeof(*(index_data->index_data_array[index].data))));
}
index_data->index_data_array[index].data->docunumber = docunum;
index_data->index_data_array[index].data->freq = freq;
}
printf("%d\n", index_data->index_data_array[0].total_docs);
printf("%s\n", index_data->index_data_array[1].word);
printf("%d\n", index_data->index_data_array[1].data->freq);
}
我得到了一個seg fault
,我似乎無法弄清楚為什么,我期望發生的是第二個 malloc 調用為index_data->index_data_array[0]
和[1]
創建空間,但也許我需要為他們留出另一個內存道路? 這個 malloc 的東西讓我想到了。
謝謝!
它已經在評論中提到了,只是為了完整起見在這里說明:你不應該從 *alloc 轉換返回值! 另外:您應該檢查 *alloc 中的所有 retval 是否為 NULL。 特別是在 realloc 的情況下,這意味着: void * tmp = realloc(old_ptr, new_size); if (!tmp) { 錯誤處理 } else { old_ptr = tmp; }
那么,現在,讓我們來解決幾個問題:
==14011== definitely lost: 96 bytes in 9 blocks
==14011== indirectly lost: 176 bytes in 5 blocks
一種。 你進入 for 循環,然后在它里面你在每次迭代中初始化 index_data!。 可能,第一個 malloc 應該在 for 循環之外(這樣可以消除前 48 個字節的內存泄漏)。
==14127== definitely lost: 192 bytes in 9 blocks
==14127== indirectly lost: 32 bytes in 2 blocks
此外,index_data->index_data_array 的第一次初始化也應該在 for 循環之前完成。 另一個 80 字節的內存泄漏消失了。
==14163== definitely lost: 64 bytes in 7 blocks
==14163== indirectly lost: 80 bytes in 3 blocks
灣為什么?:
if (index == 2) {
您正在使用current_size_outer_array
計算數組index_data_array
的元素數量。 所以用那個來檢查是否還有足夠的空間。
if (index == current_size_outer_array) {
}
另外,不要只是再次使用該值重新分配,而是在之前增加它。
if (index == current_size_outer_array) {
current_size_outer_array *= 2;
}
並使用正確的 sizeof(與上面的初始 malloc 調用相同)
if (index == current_size_outer_array) {
current_size_outer_array *= 2;
void * tmp = realloc(index_data->index_data_array, sizeof(*index_data->index_data_array)*current_size_outer_array);
if (!tmp) exit(2);
index_data->index_data_array=tmp;
}
和 ...
1
wow
6
中提琴
所以,現在這段代碼仍然在泄漏內存。 為了解決這個問題,您必須進行一些 free() 調用。
哦,我想知道我是如何發現內存泄漏的:valgrind 是你的朋友。
下面是修改后的代碼,只有功能測試,其余保持不變:
void test() {
/* Inside a function called from main */
char entered_word[4] = "wow";
int docunum = 4, index=0, freq=6, current_size_outer_array=0, current_size_inner_array=0;
int total_docs_in=1, doc_freq_pairs=1;
index_data_t *index_data=NULL;
index_data = malloc(sizeof(*index_data)*INITIAL_ALLOCATION);
index_data->index_data_array = malloc(sizeof(*index_data->index_data_array)*INITIAL_ALLOCATION);
current_size_outer_array = INITIAL_ALLOCATION;
for (index=0; index<4; index++) {
if (index == current_size_outer_array) {
current_size_outer_array *= 2;
void * tmp = realloc(index_data->index_data_array, sizeof(*index_data->index_data_array)*current_size_outer_array);
if (!tmp) exit(2);
index_data->index_data_array=tmp;
}
index_data->index_data_array[index].word=malloc(strlen(entered_word)+1);
index_data->index_data_array[index].word=entered_word;
index_data->index_data_array[index].data = (word_data_t *)malloc(sizeof(word_data_t)*INITIAL_ALLOCATION);
current_size_inner_array = INITIAL_ALLOCATION;
index_data->index_data_array[index].total_docs=total_docs_in;
if (/* Need more data points */ doc_freq_pairs<2) {
index_data->index_data_array[index].data = realloc(index_data->index_data_array[index].data, current_size_inner_array*(sizeof(*(index_data->index_data_array[index].data))));
}
index_data->index_data_array[index].data->docunumber = docunum;
index_data->index_data_array[index].data->freq = freq;
}
printf("%d\n", index_data->index_data_array[0].total_docs);
printf("%s\n", index_data->index_data_array[1].word);
printf("%d\n", index_data->index_data_array[1].data->freq);
}
重新分配你剛剛 malloced 的東西(你做了兩次)對我或其他任何人來說很可能沒有意義。
此外,您還應該將字符串 strcpy 到您分配的緩沖區,而不是用臨時 const char * 對象之一覆蓋緩沖區指針。
首先,就像 Michael Walz 所說:請始終包含一個 SSCCE ( http://sscce.org/ ),即可以編譯並演示您的問題的東西。 因此,將所有內容放在新創建的主函數中的注釋“從 main 調用的函數內部”之后,添加 printf 語句並編譯,我得到 15 個錯誤。
example.c:28:57: error: 'INITIAL_ALLOCATION' undeclared (first use in this function)
example.c:29:69: error: expected expression before '>' token
example.c:30:71: error: 'current_size_outer_array' undeclared (first use in this function)
example.c:31:2: error: expected ';' before 'index_data'
example.c:32:30: error: array subscript is not an integer
example.c:32:43: error: 'entered_word' undeclared (first use in this function)
example.c:33:30: error: array subscript is not an integer
example.c:34:30: error: array subscript is not an integer
example.c:34:54: error: 'word' undeclared (first use in this function)
example.c:35:30: error: array subscript is not an integer
example.c:35:66: error: expected expression before '>' token
example.c:35:45: error: too few arguments to function 'realloc'
example.c:36:2: error: expected ';' before 'index_data'
example.c:37:30: error: array subscript is not an integer
example.c:37:51: error: 'freq' undeclared (first use in this function)
還有其他警告,但只要代碼甚至無法編譯,我就不關心它們。
所以,主要問題是:什么是 INITIAL_ALLOCATION? 0? 1? 42?
其次:為什么立即 malloc 然后重新分配? (我太慢了,朱利葉斯也提到過)
index_data->index_data_array = (data_t*)malloc(sizeof(*index_data- >index_data_array)*INITIAL_ALLOCATION);
index_data->index_data_array = realloc(index_data->index_data_array, current_size_outer_array*sizeof(*(index_data->index_data_array)))
什么是 current_size_outer_array?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.