2015-02-11 3 views
0

В процессе отладки я обнаружил, что моя программа останавливается: «cout < < * ptr; cout < <« \ n »; что не так с этим кодом?Что случилось с отменой этого указателя?

#include<iostream> 

using namespace std; 
int *ptr = 0; 
void myfun(void); 

int main() 
{ 
    void myfun(); 
    for(int j = 1; j < 3; j++) 
    { 
     ptr = ptr-j ;  
     cout << *ptr ; cout << "\n"; 

    } 
    return(0); 
} 

void myfun(void) 
{ 
    int x[3] = {11,12,13}; 
    for(int i = 0; i <3; i++) 
    { 
     ptr = &x[i]; 
     ptr = ptr+1; 
    } 
} 
+5

'недействительным myfun();' не вызывает функцию. Это объявление функции. –

ответ

0

После выполнения приведенных выше ответов и небольшого количества поисковых запросов я выяснил точное решение моей проблемы: вернуть массив с переменным размером из функции.

Это код:

#include<iostream> 

using namespace std; 
int * myfun(void); 

int main() 
{ 
    int *ptr; 
    ptr = myfun(); 
    int len = (sizeof(ptr)/sizeof(*ptr)); 
    for(int j = 0; j <= len; j++) 
    { 
     cout << ptr[j]; 
    } 
    return(0); 
} 
int * myfun() 
{ 
    static int x[3] = {11,12,13}; 
    return x; 
} 
+0

Извините, но это неправильно. Единственная причина, по которой «работает», состоит в том, что размер указателя бывает в два раза больше из int в вашей среде.Кроме того, если бы он работал, то в чем мотивация использовать «<=» в вашем цикле вместо «<»? Попробуйте добавить еще один номер в свой массив и посмотреть сами. – rjnilsson

+0

Чем бы быть правильным методом для этого? – explorer

+0

Если вызываемая функция отвечает за определение размера массива, тогда также должен быть возвращен размер этого массива от функции. Одна из возможностей заключается в использовании аргумента «out» типа size_t *. Однако я бы посоветовал вам изучить динамическое распределение памяти, чтобы решить эту проблему более общим образом; т. е. malloc/free et al. – rjnilsson

8

Вы инициализируется указатель с нулевым

int *ptr = 0; 

, что означает, что это нулевой указатель.

Затем вы применяете арифметику указателя к нулевому указателю. Поведение не определено. Вы разыскиваете бессмысленный указатель, полученный таким образом. Поведение не определено.

Обратите внимание, что

void myfun(); 

в main не вызов функции, это объявление функции. Вызов myfun (который, по-видимому вашего намерения) будет выглядеть следующим образом

myfun(); 

Почему вы положили, что void там в вашей версии кода?

+0

Я получил свою ошибку. Теперь я получаю 13,0,0 в качестве вывода. Что я должен сделать, чтобы получить 13,12,11? – explorer

+0

@jeniShah Это совершенно другой вопрос. – JustSid

+3

В любом случае myfun устанавливает указатель, указывающий на место в стеке, которое становится недействительным, как только myfun выйдет. Кроме того, последняя итерация цикла устанавливает указатель на местоположение за пределами массива, что также не определено. Затем основная функция вычитает из указателя всего 6, что приводит к позиции до начала текущего недопустимого массива. С этим кодом слишком много проблем, чтобы даже представить себе, какая должна быть правильная версия. –

0

Ваш переменный ptr является диким указателем.

Хотя вы позволили ptr портировать массив x, когда myfun() закончил и вернул память x, был разрушен. Таким образом, в основной функции ptr становится диким указателем, и ваша программа выйдет из строя.

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

+0

«Я получил свою ошибку. Теперь я получаю 13,0,0 в качестве вывода.Что мне делать, чтобы получить 13,12,11 " Хотя у вас есть ответ на печать, это небезопасно, и ваша программа имеет потенциальную проблему с сбоем. –

0

Основная функция не имеет доступа к данным, так как область массива x [3] является myfun (void). После myfun вызов (он должен быть myfun(); вместо void myfun();), ptr будет указывать на нераспределенную ячейку памяти.

Чтобы распечатать данные в основной функции, вы можете объявить int x[3] глобальной переменной.

int *ptr = 0; 
void myfun(void); 

int x[3] = {11,12,13}; 

int main() 
{ 
    int *temp_ptr; 
    myfun(); 
    temp_ptr = ptr; 
    for(int j = 1; j <= 3; j++) 
    { 
     temp_ptr = ptr-j ;  
     cout << *temp_ptr ; cout << "\n"; 

    } 
    return(0); 
} 
+0

моя цель - вернуть значения, сгенерированные внутри функции. dnt знать длину массива заранее. – explorer

+0

Тогда вам нужно вернуть указатель с выделенной памятью –

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