2014-10-28 2 views
0

Ниже приведены два фрагмента кода. Один работал правильно, но другой провалился.
Основная функцияПередача и возврат массивов (код C)

int main 
{ 
int *x,*y,n,*c; 
//some code 
c=myfunc(x,y,n); 
//rest code 
} 

Вот код, который работал:

int * myfunc(int *a, int *b, int n) 
{ 
int *s,i,*t; 
for(i=0;i<n;i++) 
    s[i]=x[i]+y[i]; 
t=s; 
return s; 
} 

А вот код, который не работает

int * myfunc(int *a, int *b, int n) 
{ 
int s[100],i,*t; 
for(i=0;i<n;i++) 
    s[i]=x[i]+y[i]; 
t=&s[0]; 
return t; 
} 

Что здесь происходит, что даже несмотря на то, возвращаемое значение является правильным адресом (проверено и проверено), содержимое, похоже, было модифицировано самостоятельно. Однако это не похоже на первый сценарий.
Не только это, но и весь массив s [100] имеет различное содержимое в конце выполненного запроса. Что в основном означает, что содержимое всех этих адресов становится модифицированным из-за какой-то случайной причины.

--Edit--
Вопрос в прямом выражении:
Почему содержимое s при инициализации как s [100] сбрасывается после возврата и где в качестве содержимого s при инициализации как * s не сбрасывается. Обратите внимание: я не использовал malloc() или функции, которые имеют какое-либо отношение к стекам в любом месте моего кода.

** Компилятор использовался был Turbo C **.

+0

Этот вопрос не совсем подходит к моему запросу. Мое сомнение в том, почему работает инициализация * s, а не s [100]. Остальная часть моего кода просто такая же. Не используется функция malloc(), без осложнений. – n0tty

+0

См. Мой другой комментарий. В обоих случаях, насколько мы можем видеть (кроме скрытой, сверхсекретной инициализации 'int * s'), у вас есть неопределенное поведение. Нет никаких оснований ожидать, что любая версия сделает что-нибудь в частности. Переместите некоторый код вокруг, переупорядочите некоторые вызовы функций, другая версия может теперь * отображаться * работать. Ни * * * не должен * работать по какой-либо веской причине. –

+0

Извините за секретную инициализацию lol ... Я думал, что это будет просто кусок нежелательного кода, потому что в нем ничего особенного не делается. Добавлена ​​целая функция в вопросе. Спасибо – n0tty

ответ

0

Ничего случайного об этом. Вы возвращаете адрес локальной переменной, которая перестает существовать после возвращения функции. Это пространство освобождается для будущих вызовов функций, переменных и т. Д.

int * myfunc(int *a, int *b, int n) 
{ 
    int s[100],i,*t; 
    //some operation 
    t=&s[0]; 
    return t; 
}    // <!-- s is no longer valid after this point, so t is pointing nowhere 
+0

В рабочем коде я инициализировал _s_ as _ * s_, что является еще одним указателем. И операции, выполненные над ним, были такими же, как и то, что было сделано на s [100]. Я понимаю, что объявление массива находится в локальной области действия функции, но тогда у указателей есть глобальная область видимости? – n0tty

+0

№.Но тогда вы никогда не показывали нам, как '' 'был инициализирован в рабочем коде. Я предположил, что вы выделили память (через 'malloc()' и т. Д.) - в этом случае область не имеет к этому никакого отношения. 'malloc()' -ed память существует, пока вы не назовете 'free()' на ней. –

+0

Эй! Это прекрасно! malloc() и другие функции не использовались в коде. Но вопрос в том, почему ** инициализирует int * s, а затем делает t = s; и возвращение т хорошо работает? Разве это не локальная переменная? Или определение указателя делает его общедоступным? ** – n0tty

0

В коде, который не работает, s[100] является массивом в стеке и выходит из области действия при возврате функции. В рабочем коде вы не показываете, как выделяется s, но предположительно это с malloc или некоторым другим распределением, отличным от стека.

В общем случае вы не должны возвращать указатели на переменные стека, поскольку переменные стека будут перезаписаны, как только функция вернется.

PS. получить настоящий компилятор уже :)

+0

В рабочем коде я инициализировал _s_ as _ * s_, что является еще одним указателем. И операции, выполненные над ним, были такими же, как и то, что было сделано на s [100]. Я понимаю, что объявление массива находится в локальной области действия функции, но тогда у указателей есть глобальная область видимости? – n0tty

Смежные вопросы