这个问题在这里已有答案:
我试图了解C行为并发现了一些奇怪的事情。我调试并发现表值是正确的,直到调用printf。我创建一个void函数来测试它是否是范围问题,但在调用此函数后,表值仍然保持正确。我现在想知道printf是否删除了以前的局部变量。
#include <stdio.h>
#include <stdlib.h>
void invertTable(int** tableau,int size){
int temp[size];
for(int i = 0; i < size; i++)
{
temp[i]=-1*tableau[0][i];
}
tableau[0]=temp;
}
void test(){
}
int main(int argc, char const *argv[])
{
int* table=(int*)malloc(5*sizeof(int));
table[0]=1;
table[1]=2;
table[2]=3;
table[3]=4;
table[4]=5;
invertTable(&table,5);
test();
for(int i = 0; i < 5; i++)
{
//Here is the problem
printf("\n %d \n",table[i]);
}
free(table);
return 0;
}
预计-1 -2 -3 -4 -5
输出:-1 1962295758 1 1962550824 1962295741
要获得正确的输出,您应该更改
int temp[size]
到int* temp = *tableau
或int* temp = (int*) malloc(sizeof(**table) * size)
。
这些解决方案的工作原理是因为*tableau
和/或malloc
分配的内存在invertTable
之后没有被破坏。
通常temp
应该在invertTable
函数之后销毁并使tableau[0]
成为悬空指针然后系统可以重新分配temp
所指向的记忆。因此,这部分内存现在可能包含随机数据。这些数据可能是您执行程序时获得的数据。
我调试了你的代码,是的,调用printf
时出现问题。对于那些不相信我的人,调试它并一步一步地观看tableau
内容。我无法解释为什么所有这一切都发生在调用printf
之后。在调用printf
之前,tableau
的内容确实是正确的。
我不确定,但这可能与heap
有关。
您的问题与printf无关,这是由于您的代码中的一个错误,您尝试使用您不应该使用的内存。
在你的invertTable
函数的这一行:
tableau[0]=temp;
您将main()函数中的table
指针指向本地temp
变量。
当temp
函数结束时,你的invertTable
数组超出了范围,所以你最终得到一个悬空指针,你不能再使用那个内存 - 这样做是未定义的行为。
您可以改为动态分配内存,在invertTable
结束后保持有效:
int *temp = malloc(sizeof(int) * size);
for(int i = 0; i < size; i++)
{
temp[i]=-1*tableau[0][i];
}
//deallocate previous allocation
free(tableau[0]);
tableau[0]=temp;
你的问题与printf
无关,确实是invertTable
,这是罪魁祸首。
处理数组时table
等于&table[0]
所以在这种情况下,你不需要发送tableau的地址。
#include <stdio.h>
#include <stdlib.h>
void invertTable(int *tableau,int size){
for(int i = 0; i < size; i++)
{
tableau[i] = -1 * tableau[i];
}
}
void test(){
}
int main(int argc, char const *argv[])
{
int* table = (int*) malloc(5 * sizeof(int));
table[0]=1;
table[1]=2;
table[2]=3;
table[3]=4;
table[4]=5;
invertTable(table,5);
test();
for(int i = 0; i < 5; i++)
{
//Here is the problem
printf("\n %d \n",table[i]);
}
free(table);
return 0;
}
这将做你想要的。另外,您也不需要使用任何临时变量。
顺便说一句,temp
是临时的,它没有在堆上分配,所以当invertTable
返回时它被销毁。
tableau[0]=temp;
这是无效的。这意味着返回指向本地数组的指针。这是未定义的行为。
你可以这样做:
for(int i = 0; i < size; i++)
(*tableau)[i]*=-1;