指针数组内容在传递给 C 中的函数时被擦除

Posted

技术标签:

【中文标题】指针数组内容在传递给 C 中的函数时被擦除【英文标题】:Pointer array contents wiped when passed to a function in C 【发布时间】:2017-04-07 16:52:05 【问题描述】:

所以我从文本文件加载浮点数行并将它们存储在指针数组中,然后将它们保存回文本文件并添加对其大小的引用。文本文件中的值数量不同,因此数组必须是动态的。我像这样在 main 中定义我的指针数组。

size_t size = (int)100 * sizeof(float);
float * val = malloc(size);

然后我将指针数组传递给加载文本文件并将值保存到其中的函数,就像这样。

//Read file into array.
int readFile(float *val, int size) 

char buf[20] =  0 ;
val[0] = 0;
double temp = 0;
int i = 1;
FILE *file;
file = fopen("C:\\Users\\MoldOffice\\Dropbox\\VS\\finalproj\\ecgproject\\dataStream", "r");
if (!file) 
    printf("Coulding find file.\n");
    exit(1);


while (fgets(buf, 20, file) != NULL) 
    temp = atof(buf);
    if (temp != 0) 
        // Increment i to find the size of the useful data.
        val[i] = temp;
        //printf("%d",val[i]);
        i++;
        if (i == size / sizeof(float)) 
            size += 100*sizeof(float);
            double* val_temp = realloc(val, size);
            if (val_temp == NULL) 
                printf("Realloc failed.\n");
            
            else 
                val = val_temp;
            
        
    

//Test that the array is readable.
for (int i = 0; i < 5; i++) printf("val[%d]=%f\n", i, val[i]);

return(i);
fclose(file);

这很好用,当我在 main 中打印指针数组的内容时,它可以工作。然后我将相同的指针数组传递给另一个函数,该函数将数组保存在一个新的文本文件中,连同第一行的大小,问题是当我第二次传递指针数组时,内容已经改变(主要是0 和一些随机数)。我完全不知道为什么会这样。有什么想法吗?写入文件的函数在这里:

// Write file into array.
void writeFile(float *val,int size) 

printf("%d",sizeof(val));
FILE *file;
int sampleNum;
char buf[10];
file = fopen("sampleNum.txt", "r");
if (file == NULL)  sampleNum = 0; 
else  fscanf(file, "%d", &sampleNum); printf("%d",sampleNum);
char fileString[10];
sprintf(fileString,"sample%d\0", sampleNum);
file = fopen(fileString, "w");

//Test that the array is readable.
for (int i = 0; i < 5; i++) printf("val[%d]=%f\n", i, val[i]);

//Print the array to a text file and save.
fprintf(file, "%d\n", size);
for (int i = 1; i < size; i++) 
    fprintf(file, "%f\n", val[i]); 
    printf("%f\n", val[i]); 
fclose(file);

main 的其余部分可以在这里找到:

int main() 

size_t size = (int)100 * sizeof(float);
float * val = malloc(size);

// Read the data into an array.
int arraySize = readFile(val, size);

//Test that the array is readable.
for (int i = 0; i < 5; i++) printf("val[%d]=%f\n", i, val[i]);

// Save the array to a text file, with the size of the array as the first element.
writeFile(val,arraySize);


【问题讨论】:

请您将其简化为minimal test-case。例如,如果问题与调用函数有关,则将数据写入文件的代码可能无关紧要。 搜索并阅读有关在 c 中模拟通过引用传递 现在会这样做。 另外,如果你声明一个函数返回一个值,它必须实际返回一个值,否则你将有未定义的行为 您的readFile 没有返回任何内容。警告会告诉你。 【参考方案1】:
        double* val_temp = realloc(val, size);
        if (val_temp == NULL) 
            printf("Realloc failed.\n");
        
        else 
            val = val_temp;

此函数的调用者无法知道您已将数组移动到不同的位置。它仍然有旧的、现在无效的指针。

size 也有类似的问题。来电者怎么知道你改变了它?

你选择的职责分工很差。如果调用者负责分配缓冲区,那么这个函数应该要求调用者扩大它。如果这个函数负责分配缓冲区,它应该分配它。将管理一块内存分配的责任分开通常是一个非常糟糕的主意,这说明了其中一个原因。

也许传入一个指向结构的指针,该结构包含指向缓冲区的指针及其大小?这会行得通,但仍然表明职责分工很差。

也许让这个函数分配缓冲区并返回一个结构,其中包含指向它的指针和其中的元素数量?

如果您真的想这样做,请考虑向函数传递一个指向结构的指针,该结构包括指向数组的指针、数组的大小以及指向调整数组大小的函数的指针。调用者当然可以将此指针设置为指向realloc 函数(尽管它可能是一个更改结构的指针和大小成员的函数更好)。

你也可以使用这样的代码:

struct float_buffer

    float* buffer;
    int size;
;

struct float_buffer allocate_float_buffer(int size)

    struct float_buffer buf;
    buf.buffer = malloc (size * sizeof(float));
    buf.size = size;
    return buf;


bool resize_float_buffer(struct float_buffer* buf, int size)

    float* tmp = realloc(buf->buffer, size * sizeof(float));
    if (tmp == NULL)
        return false;
    buf->buffer = tmp;
    buf->size = size;
    return true;

然后给函数传递一个struct float_buffer *

【讨论】:

对不起,函数的调用者是什么意思?它被分配到的变量?我没有计算机科学背景! “函数的调用者”是指任何代码调用包含我在答案中摘录的代码的函数。您向此函数传递一个指向缓冲区及其大小的指针。但它真正需要的是指向缓冲区的指针、缓冲区的大小以及调整缓冲区大小的方法。 你认为我应该只在 val 上使用 realloc 吗? 这并不能解决任何问题。调用者仍然无法知道val(在此函数中)的值发生了变化。您按值传递了指针和大小。 哦,好吧,我想我明白了……我可能需要把它写在纸上,然后盯着看一会儿。

以上是关于指针数组内容在传递给 C 中的函数时被擦除的主要内容,如果未能解决你的问题,请参考以下文章

将二维数组指针传递给c ++中的函数[重复]

指针在函数中的作用

C语言基础:C 中数组详解(多维数组传递数组给函数 从函数返回数组 指向数组的指针 )

C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?

c语言 指针传参

将指针数组传递给函数指针数组的 C++ 问题