Статьи Галерея Форум Чат Файлы HowTo Ссылки Поиск
Текущее время: 25 авг 2019, 22:15




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: C и возрашение указателя
СообщениеДобавлено: 13 май 2006, 20:21 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
Собственно есть C, gcc и этот код:
Код:
#include <stdlib>
#include <stdio>

void ss(char *tr)
{
     tr = (char *)malloc(50);
     tr = "aaaa!";
}

int main(int argc, char **argv)
{
     char *ptr;
     ss(ptr);
     printf("%s", ptr);
     return 0;
}


Проблема заключается в том, что память выделяется, но изменить эту память не получается - printf печатает что угодно, то только не строку "aaaa!".
Как решить эту проблему?
PS Смотрел дебагером в main адрес в ptr один, в ss другой, но когда возвращается обратно в main адрес в ptr остается прежним.


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 14 май 2006, 02:50 
Заглянувший

У нас с: 30.12.2004
Сообщения: 5
2Silos: у тебя в коде по крайней мере 2 ошибки. Во-первых, чтобы ss изменяла значение ptr в main, нужно его передавать не по значению, а по ссылке( void ss(char* &tr) ). А во-вторых, ты выделяешь память в ss и потом теряешь указатель на нее, соответственно не освобождаешь. ИМХО у тебя проблема в понимании способов передачи параметров, а также представления строк и работы с памятью в C.


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 14 май 2006, 09:46 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
Вообще C я никогда не учил. А сейчас понадобилось.
Вот методом проб и ошибок написал окло 70% программы, но из за незнания как передать по ссылке застопорился.
В данном случае память можно не освобождать, ибо прграмма тестовая и очень быстро завершается. А как известно после завершения OS сама освободит занаятую память.
Проблемы понимания у меня нету, есть только проблема незнания:)
Спасибо!


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 14 май 2006, 11:04 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 28.11.2003
Сообщения: 861
Откуда: Минск
Silos, Почитай хоть какую книжку по С.

Указатели, массивы и управление памятью описаны в любой их них.
Перед тем как писать программы на С это просто необходимо. Иначе
потом никто не разберется без больших трудностей.

Особенно код функции ss() страшен. Ты думал что

tr = "aaaa!";

занесет строку по адресу в tr? Это просто ужасная ошибка.


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 15 май 2006, 08:55 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 08.03.2004
Сообщения: 338
1. Коль скоро ss(char *tr) изменяет указатель, то её аргумент должен быть двойным указателем: char** tr.
Передача аргумента должна выглядеть так: ss (&ptr);
2. tr = "aaaa!"; - а это вообще страх господень...
Это не паскаль. Такое присваивание изменяет адрес, "содержащийся в указателе", а не то, на что указывает указатель. Для операций со строками есть целая толпа функций str*(), mem*().

xaep,
В С++ допустим т.н. ссылочный тип - (char& tr), к-й недопустим в C. (Усли речь шла об это?) Если речь шла о нём, то объявление ss (char* &tr) выглядит как-то странно... :wink:

_________________
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 20 май 2006, 21:07 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
Спасибо за помощь, разобрался!

exe, вот часть кода и код main.c для тестирования:

main.c
Код:
#include <stdlib>
#include <stdio>
#include "s_math.h"

int main()
{
   const char *inte = "int(f(x^2)d(x/2))";
   char *f_x, *d_x;
   s_int_parse(inte, &f_x, &d_x);
   printf("f(x) = %s\nd(x) = %s\n", f_x, d_x);

   free((void *)d_x);
   free((void *)f_x);

   return 0;
}



s_math.h
Код:
#ifndef S_MATH_H
#define S_MATH_H

int s_int_parse(const char *s, char **f_x, char **d_x);

#endif



s_math.c
Код:
#include <stdlib>

#include "s_string.h"

int s_int_parse(const char *s, char **f_x, char **d_x)
{
   char *pinte = malloc(s_len(s) - 4);
   int rc = s_cut(s, pinte, 4, s_len(s));
   char *ff_x = malloc(rc - 2);
   char *dd_x = malloc(rc - 2);
   char *gap = ")d(";
   rc = s_break_two(pinte, ff_x, dd_x, gap, 1);
   *f_x = (char *)malloc(rc - 2);
   *d_x = (char *)malloc(s_len((char *)d_x) - 2);
   (void)s_cut(ff_x, *f_x, 2, rc);
   (void)s_cut(dd_x, *d_x, 2, s_len(dd_x));

   free((void *)dd_x);
   free((void *)ff_x);
   free((void *)pinte);

   return 0;
}



По моему, этот код легко читаем:)


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 20 май 2006, 21:51 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 28.11.2003
Сообщения: 861
Откуда: Минск
Silos, Тебе может и легко, ты его создавал. Но могу гарантировать, забудешь через пару месяцев.

Можно пожужжать :-) ? Это не издевательство, не указание на незнание, а просто code review. Вдруг задумаешся...

1. Где комментарии?
2. На некоторых платформах #include <malloc> пригодится
3. malloc возвращает void *, не везде есть преобразование (char *).
4. char *gap = ")g("; не смотрится
и так далее.

А самое главное, запуск из-под valgrind что говорит?
Я вижу 5 malloc, 3 free. А что valgrind --tool=memcheck говорит?

Можешь все мои комменты выбросить далеко, если не применимы.


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 20 май 2006, 23:27 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
Код:
3. malloc возвращает void *, не везде есть преобразование (char *).

Тоесть для правильности работы "везде" необходимо писать (char *)malloc?

Код:
2. На некоторых платформах #include <malloc> пригодится

А как это определить, где необходимо, а где нет?

Цитата:
1. Где комментарии?

Все их дикое количество было вырезано, что бы сюда запостить.
Не постить же 20 kb кода?
Меня один раз kife попинал за отсутствие таковых, так теперь коментирую, все что могу забыть, или же может быть полезно знать другому:)

Цитата:
4. char *gap = ")g("; не смотрится

Тоесть?

Цитата:
А самое главное, запуск из-под valgrind что говорит?
Я вижу 5 malloc, 3 free. А что valgrind --tool=memcheck говорит?


Код:
[silos@asakura s_lib]$ valgrind test
==2790== Memcheck, a memory error detector.
==2790== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==2790== Using LibVEX rev 1471, a library for dynamic binary translation.
==2790== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==2790== Using valgrind-3.1.0, a dynamic binary instrumentation framework.
==2790== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==2790== For more details, rerun with: -v
==2790==
==2790==
==2790== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2790== malloc/free: in use at exit: 0 bytes in 0 blocks.
==2790== malloc/free: 30 allocs, 30 frees, 1,981 bytes allocated.
==2790== For counts of detected errors, rerun with: -v
==2790== No malloc'd blocks -- no leaks are possible.
[silos@asakura s_lib]$ valgrind --tool=memcheck test
==2799== Memcheck, a memory error detector.
==2799== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==2799== Using LibVEX rev 1471, a library for dynamic binary translation.
==2799== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==2799== Using valgrind-3.1.0, a dynamic binary instrumentation framework.
==2799== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==2799== For more details, rerun with: -v
==2799==
==2799==
==2799== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
==2799== malloc/free: in use at exit: 0 bytes in 0 blocks.
==2799== malloc/free: 30 allocs, 30 frees, 1,981 bytes allocated.
==2799== For counts of detected errors, rerun with: -v
==2799== No malloc'd blocks -- no leaks are possible.
[silos@asakura s_lib]$


Цитата:
Можешь все мои комменты выбросить далеко, если не применимы.

Тише... Что мне давно не хватало, так это code review.
Вообщем то это хорошо.
Чем больше code review, тем лучше код!
:D :D
Вообщем было бы очень хорошо, если бы вы могли продолжить, я б исходники выслал бы, или бы выложил:)


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 02:02 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 08.03.2004
Сообщения: 338
exe, #include <malloc> ?
А откуда такое? malloc без .h как-то на С++ смахивает :D Или может имеется в виду #include <malloc> ? Нет, на самом деле, без иронии, интересно.

Silos, может я ошибаюсь, но мне кажется, что правила хорошего тона требуют, чтобы всё, что было захвачено, было и освобождено (когда оно уже не нужно). Т.е., другими словами, на каждый malloc() должен быть свой free().

_________________
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 02:10 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 08.03.2004
Сообщения: 338
Рискну ответить сам себе по поводу первого... По непонятным причинам после malloc проглатывается точка h.....

_________________
Ну какая работа со строками может быть в языке, название которого является не строкой, а символом? (c) Sergue E. Leontiev


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 11:12 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 28.11.2003
Сообщения: 861
Откуда: Минск
Вот и мой review накрылся :-) просто забыл .h

насчет везде (char *) - правило хорошего тона. С проглотит и не поморщится и без него.

char *gap используется один раз - либо выкинь, либо определи как
константу или #define вверху. Считается более читабельным.


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 13:24 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
red f0x, на каждый malloc свой free.
Просто это кусок кода.

exe, действительно, лучше выкинуть - чавой то я записался совсем.....

Спасибо!


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 13:53 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 28.11.2003
Сообщения: 861
Откуда: Минск
red f0x, Ты прав насчет malloc()/free(), но посмотри не вывод
valgrind - нету потери памяти. Значит у него где-то free() запрятан
при вызове других функций.

Silos, Будь осторожен с такими передачами - сложно уследить
за всеми указателями.


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 16:37 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 15.02.2004
Сообщения: 287
Откуда: Belarus, Minsk
exe, без осторожности и внимательности здесь никак.
Протестировал я свою программу valgrind'ом(это около 1000 строк) - утечек не было обнаружено. Это уже радует:)

Тут встал другой вопрос:
Необходимо сделать функцию наподобие printf() - зарание не известно сколько ей будет передано аргументов. Как реализовать?
Или же смотреть в сторону масивов указателей?


Вернуться к началу
 Не в сети Профиль Личный альбом  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: 21 май 2006, 17:14 
Неотъемлемая часть форума
Аватара пользователя

У нас с: 28.11.2003
Сообщения: 861
Откуда: Минск
#include <stdargs>

extern void trPrintf(int flag, char *fmtStr, ...);
void trPrintf(int flag, char *fmtStr, ...)
{
va_list argP;
int save_errno = errno;

va_start(argP, fmtStr);
vsprintf(msgBuf, fmtStr, argP);
va_end(argP);

if (trPrintFunction == (traceHandler) NULL)
fprintf(stderr, "%s\n", msgBuf);
else
(*trPrintFunction)(msgBuf);

errno = save_errno;
}


Вернуться к началу
 Не в сети Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
[ All resources are available under GNU GPL ] [ Support ] [ Hosted by DataHata | MyCloud.by ] [ Powered by phpBB® Forum Software © phpBB Group ]

LVEE Winter LVEE Rambler's Top100