簡體   English   中英

段錯誤 - 錯誤分配?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM