簡體   English   中英

C程序設計:創建和寫入二維文件數組作為函數

[英]C programming: Create and write 2D array of files as function

我有一個很長的程序,我想縮短它。 我經常編寫2d文件數組,但是我在整個程序中重復了數十次此過程,因此我試圖將其編寫為一種函數,以減少我自己的錯誤,並使代碼更短,更易於閱讀。

我正在修改從函數C中分配內存2d數組獲得的示例但使用FILE數組代替。

我已經可以很容易地在main中分配2D文件數組,但是再次,我想將其作為函數來執行:

#include <stdio.h>
#include <stdlib.h>

void allocate_mem(FILE**** arr, const int n, const int m) {
    arr = malloc(n*m*sizeof(FILE));
    for(int i=0; i<n; i++) {
        arr[i] = malloc(m*sizeof(FILE));
        for (unsigned int j = 0; j < m; j++) {
            char filename[64];
            sprintf(filename,"tmp_%d_%d.txt",i,j);
            *arr[i][j] = fopen(filename,"w");
            fprintf(*arr[i][j],"blah %d %d\n",i,j);
        }
    }
}

void deallocate_mem(FILE**** arr, const int n, const int m){
    for (int i = 0; i < n; i++) {
        for (unsigned int j = 0; j < m; j++) {
            fclose(*arr[i][j]);
        }
        free((*arr)[i]);
    }
    free(*arr); 
}

int main() {
    FILE ***array;
    allocate_mem(&array,5,3);
    deallocate_mem(&array,5,3);
    return 0;
}

我已經嘗試了幾乎所有可能的方法(無論如何對我而言),但是我不斷從valgrind中得到這樣的錯誤:

==16192== HEAP SUMMARY:
==16192==     in use at exit: 4,440 bytes in 3 blocks
==16192==   total heap usage: 3 allocs, 0 frees, 4,440 bytes allocated
==16192== 
==16192== Searching for pointers to 3 not-freed blocks
==16192== Checked 70,808 bytes
==16192== 
==16192== 552 bytes in 1 blocks are still reachable in loss record 1 of 3
==16192==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16192==    by 0x4EA711C: __fopen_internal (iofopen.c:69)
==16192==    by 0x40080C: allocate_mem (create_file_array.c:11)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192== 
==16192== 648 bytes in 1 blocks are still reachable in loss record 2 of 3
==16192==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16192==    by 0x4007AC: allocate_mem (create_file_array.c:7)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192== 
==16192== 3,240 bytes in 1 blocks are still reachable in loss record 3 of 3
==16192==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16192==    by 0x400761: allocate_mem (create_file_array.c:5)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192== 
==16192== LEAK SUMMARY:
==16192==    definitely lost: 0 bytes in 0 blocks
==16192==    indirectly lost: 0 bytes in 0 blocks
==16192==      possibly lost: 0 bytes in 0 blocks
==16192==    still reachable: 4,440 bytes in 3 blocks
==16192==         suppressed: 0 bytes in 0 blocks
==16192== 
==16192== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==16192== 
==16192== 1 errors in context 1 of 2:
==16192== Invalid write of size 8
==16192==    at 0x40080D: allocate_mem (create_file_array.c:11)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==16192== 
==16192== 
==16192== 1 errors in context 2 of 2:
==16192== Use of uninitialised value of size 8
==16192==    at 0x40080D: allocate_mem (create_file_array.c:11)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192==  Uninitialised value was created by a heap allocation
==16192==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16192==    by 0x4007AC: allocate_mem (create_file_array.c:7)
==16192==    by 0x400951: main (create_file_array.c:29)
==16192== 
==16192== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
create_file_array.c

我怎樣才能使allocate_mem和deallocate_mem工作?

您應該忘了聽說過三顆星或四顆星。 與酒店相比,C編程使用的是逆系統:星星越多,代碼的質量越差。

您甚至都不想要指向……的指針。您想要一個2D數組。

話雖如此,請注意,這並不是那么簡單,因為您要擁有數組的類型是FILE* 大多數想當老手的程序員都會失敗,並提出一些廢話,建議使用多個for循環和多個malloc調用,以對可憐的無辜堆發起全面的攻擊。

而是從main()開始。 為了節省理智,您可能希望主管道看起來像這樣:

int main (void) 
{
  file_arr_t* array;    // pointer to a 2D array
  array = allocate_mem(5,3);
  deallocate_mem(array);
  return 0;
}

在這種情況下, allocate_mem函數需要返回一個指向已分配數組的指針。 聲明數組指針的C語法非常糟糕,因此您需要創建一個typedef來節省理智。 typedef離開指針也是一種不好的做法,因此最好typedef一個要指向的數組類型:

typedef FILE* file_arr_t[3][5];   // type is an array of 3x5 FILE*

其中file_arr_t*指向3x5 FILE指針數組的指針 ew

然后,您可以將函數編寫為:

file_arr_t* allocate_mem (size_t x, size_t y)
{
  file_arr_t* array = malloc(sizeof(FILE*[x][y]));

  (*array)[i][j] = ... // do things with the pointer to array

  return array;
}

void deallocate_mem(file_arr_t* array)
{
  free(array);
}

編輯

如果您真正需要在運行時實現完全動態化的尺寸標注,恐怕您會陷入一種棘手的語法或另一種情況,因為那樣便無法使用typedef。 您最終會得到這樣的不可讀內容:

// turning messy, avoid writing code like this.
void allocate_mem (size_t x, size_t y, FILE* (**arr_ptr)[x][y])
{
  *arr_ptr = malloc(sizeof(FILE*[x][y]));
  (**arr_ptr)[i][j] = something;
}

int main (void)
{
  FILE* (*array)[5][3];
  allocate_mem(5, 3, &array);
}

在這種情況下,我建議只使用void*代替:

void* allocate_mem (size_t x, size_t y)
{
  // omit inner-most dimension on purpose to get clearer access syntax later
  FILE* (*array)[y] = malloc(sizeof(FILE*[x][y]));

  // now this pointer can be used with intuitive syntax:
  array[i][j] = something;
  ...

  return array;
}

int main (void)
{
  FILE* (*array)[5][3];
  array = allocate_mem(5, 3);
}

第一個問題...

void allocate_mem(FILE**** arr, const int n, const int m) {
    arr = malloc(n*m*sizeof(FILE));      // probably not what you want!
    for(int i=0; i<n; i++) {
       arr[i] = malloc(m*sizeof(FILE));  //overwrites initial value of arr when i==0!

i == 0您的初始指針由arr = malloc(n*m*sizeof(FILE)); 被覆蓋,您會泄漏(丟失可見性)該內存。 這是必須解決的。

我最初的想法是……哇! 您正在使用( FILE**** arr )指向指針的指針。 您確實需要簡化此過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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