2010-10-15 5 views
0

Здравствуйте Может кто-нибудь объяснить, почему второй соиЬ в FUNC (символ * р) не работает:C++ соиЬ указатель

#include <cstdlib> 
#include <iostream> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

using namespace std; 

char *strhex(char *str); 
char *func(char *p); 

int main() 
{ 
    char *ptr;  

    char *p=strhex("d"); 
    cout<<"main:"<<p<<endl; 

    cout<<func(p)<<endl; 

    system("PAUSE"); 
    return 0; 
} 

char *func(char *p) 
{ 
     cout<<"func1:"<<p<<endl; 
     char buffer[500]=""; 
    char *zbuffer = buffer; 
     cout<<"func2:"<<p<<endl; ///doesn't work 

     return zbuffer; 
} 

char *strhex(char *str) 
{ 
    char buffer[500]=""; 
    char *pbuffer = buffer; 
    int len = strlen(str); 

    for(int i = 0; i < len ;i++) 
    { 
    itoa(str[i],pbuffer,16); 
     pbuffer +=2; 
    }; 

    *pbuffer = '\0'; 
    pbuffer=buffer; 

    return pbuffer; 
} 

Edit: я использую DEV C++ 4.9.9.2 на Windows,

+8

Что вы подразумеваете под «не работает?» –

+0

Возврат указателя на локальную переменную, вероятно, плохая идея, но, вероятно, не связанная с вашей проблемой. –

+3

@ Карл: Наверное, точную причину, на самом деле. Пространство стека, занимаемое 'buffer' в' strhex() ', будет занимать' buffer' в 'func()'. –

ответ

4

Одна большая проблема заключается в том, что strhex возвращает указатель на локальную переменную (buffer[]). Эта переменная выходит за пределы области действия в конце функции, поэтому возвращаемое значение указывает на неопределенное содержимое памяти, которое может быть перезаписано в любое время.

1

Весь ваш код не работает. Обе функции возвращают указатели на локальные массивы, которые не указывают на что-либо действительное после возвращения функции. Это вызывает неопределенное поведение. Поскольку значение p является одним из этих недействительных указателей, вы не можете зависеть от него, чтобы быть чем-то в любое конкретное время - эта память, вероятно, будет перезаписана во время func(). Вам нужно либо new[], либо delete[] соответствующую память, либо, желательно, использовать соответствующую структуру данных C++, такую ​​как std::string.

0

похоже, что он работает, но второй cout в основном не распечатывает значение, потому что вы возвращаете пустой буфер.

0

Добавление других ответов:

Вам не нужно сбросить pbuffer, чтобы указать на начало массива, а затем вернуть его значение:

pbuffer=buffer; 
return pbuffer; 

вы можете просто сказать

return buffer; 

имя массива также является указателем (указатель на первый элемент массива.

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