Я попытался понять поведение 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
См. geeksforgeeks.org/return-local-array-c-function
Чтобы иметь правильный вывод, вы должны изменить
int temp[size]
в int* temp = *tableau
или в int* temp = (int*) malloc(sizeof(**tableau) * size)
.
Эти решения работают, потому что *tableau
и/или память, выделенная malloc
, не уничтожается после invertTable
.
Обычно temp
должен быть уничтожен после invertTable
функции и создания tableau[0]
оборванный указатель, тогда система может перераспределить память, на которую указывает temp
. Таким образом, эта часть памяти теперь может содержать случайные данные. Эти данные, вероятно, то, что вы получили во время выполнения.
Ваша проблема не связана с printf, это связано с ошибкой в вашем коде, когда вы пытаетесь использовать память, которую не должны использовать.
В этой строке в вашей функции invertTable
:
tableau[0]=temp;
Вы указываете указатель table
в функции main() на локальную переменную temp
.
Ваш массив temp
выходит за пределы области видимости, когда функция invertTable
завершается, поэтому вы получаете висячий указатель, и вы больше не можете использовать эту память - это поведение undefined.
Вместо этого вы можете динамически выделять память, которая останется в силе после окончания 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]
, поэтому в этом случае вам не нужно отправлять адрес таблицы.
#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;
Когда вы назначаете tableau[0] = temp; переменная temp является локальной, поэтому она освобождается после возврата из функции. Итак, ваша таблица указывает на нераспределенную память. Тогда поведение не определено, вызов printf, вероятно, перераспределяет часть памяти там, где была temp, поэтому вы видите мусор...