Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.10.2014, 19:51   #1
Hemul
Форумчанин
 
Регистрация: 03.10.2010
Сообщений: 321
По умолчанию Выделение памяти в функции

Код:
int func(char* str)
{
    str = new char[10];
    strcpy(str,"hello");
}

....
char *str;
func(str);
cout<<str[1]<<endl;
delete[]str;
....

Почему данный код генерирует Segmentation fault? Почему выделяемая память в func не сохраняется в указателе при выходе из функции?
Hemul вне форума Ответить с цитированием
Старый 13.10.2014, 22:36   #2
marenko.lilia
Пользователь
 
Аватар для marenko.lilia
 
Регистрация: 25.12.2013
Сообщений: 91
По умолчанию

Цитата:
Почему выделяемая память в func не сохраняется в указателе при выходе из функции?
Потому что при выходе из функции все данные уничтожаются. И копии переданных переменных, и все созданные в функции переменные, и адрес памяти которая выделена в функции. Это СТРАШНОЕ ДЕЛО - утечка памяти

Чтобы не потерять адрес памяти, выделенной в функции, надо вернуть из функции указатель на этот участок памяти и записать этот адрес в указатель, определённый в main()

Код:
#include <iostream>
using namespace std;

char* func(char* str)
{
	str = new char[10];
	strcpy_s(str, 10, "hello");

	return str;
}

int main()
{
	setlocale(LC_ALL, "rus");

	char* myStr = 0;
	myStr = func(myStr);
	cout << myStr[1] << endl;
	delete[] myStr;

	return 0;
}
marenko.lilia вне форума Ответить с цитированием
Старый 13.10.2014, 22:51   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Код:
#include <iostream>
#include <string.h>

using namespace std;
int func(char **str)
{
    *str = new char[6];
    strcpy(*str,"hello\0");
    return 6;
}
int main()
{
char *str;
int i=func(&str);
cout<<i<<str<<endl;
delete[]str;
    return 0;
}
Не?

Кстатти: http://www.programmersforum.ru/showthread.php?t=92433
I'm learning to live...

Последний раз редактировалось Stilet; 13.10.2014 в 22:54.
Stilet вне форума Ответить с цитированием
Старый 14.10.2014, 08:56   #4
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Hemul, а вообще, используйте C++ строки вместо сишных:

Код:
#include <iostream>
#include <string>

void func( std::string &str )
{
    str = "Hello";
}

int main()
{
    std::string str;
    func( str );
    std::cout << str << std::endl;
    return 0;
}
8Observer8 вне форума Ответить с цитированием
Старый 14.10.2014, 11:44   #5
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Hemul Посмотреть сообщение
Почему данный код генерирует Segmentation fault? Почему выделяемая память в func не сохраняется в указателе при выходе из функции?
Aргументы функции всегда копируются.
Внутри функции фигурирует копия указателя, а вовсе не оригинал:

Код:
char* func(char* str)
{.
	str = new char[10];   //<--- str - копия указателя, который был передан в функцию
	strcpy_s(str, 10, "hello");
	return str;
}
Вы присваиваете адрес не оригинальному указателю, а копии.
И когда функция завершается, заканчивается время жизни этой копии.

А оригинальный указатель остается без изменений.


Что бы внутри функции влиять на оригинальные данные, а не на копии, можно пойти двумя путями:

1. Путь сишника. Передавайте в функцию указатель на указатель.
Господин Stilet показал вам пример.....

Лично я считаю, что путь сишника в с++ коде это плохо.
Потому что на языке с++ можно сделать проще, безопаснее и эффективнее.


2. Путь сишника-с-крестами (в народе просто: плюснутого, приплюснутого, крестанутого, крестухана, крестобл... ну вы понэли)

Если функция ожидает реально существующий объект, и внутри функции нужно влиять на оригинал, а не на копию - передают ссылку на этот объект:


Код:
void func(char*& str)  //<--- str, это ссылка на оригинальный указатель
{
    str = new char[10]; //<--- изменяем содержимое оригинального указателя
    strcpy(str,"hello");
}

....
char *str;
func(str);
cout<<str[1]<<endl;
delete[]str;
....

Последний раз редактировалось _Bers; 14.10.2014 в 12:11.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распределение памяти. Динамическое выделение памяти с++ Tolian92 Помощь студентам 8 14.05.2012 21:44
Язык СИ! Динамическое выделение памяти под массивы и матрицы, передача матрицы в функции Андрей! Общие вопросы C/C++ 33 31.01.2012 22:07
Выделение памяти в функции SVLay Visual C++ 4 22.01.2012 16:53
Выделение памяти antoha.by Паскаль, Turbo Pascal, PascalABC.NET 2 29.04.2008 20:04
Выделение памяти в функции для переданных параметров LinuxUser Общие вопросы C/C++ 1 12.11.2007 19:21