LINUX.ORG.RU

realloc и массив указателей типа char*


0

2
	int x = 0;
	for (i = 4; i <= 31; i++ && x++)
		if (code.l & (1 << i))
		  {
		    if (x == 0)
		      {
			info.bios_info->characteristics = (char**) malloc (sizeof (char*));
			info.bios_info->characteristics[x] = characteristics[i-3];
		      }else
		      {
		        realloc (info.bios_info->characteristics, (sizeof(char*) * x));
			info.bios_info->characteristics[x] = characteristics[i - 3];
		      }
		  }  

Результат:

*** glibc detected *** ./HardInform: realloc(): invalid next size: 0x082dc690 ***

ЧЯДНТ?

★★

>realloc() returns a pointer to the newly allocated memory

Присвоить значение, не?

roy ★★★★★
()

Хотя выводимая ошибка не про это...

roy ★★★★★
()

Как на счёт того, чтобы наконец таки заглянуть в мануал? Например, realloc() возвращает указатель на новый массив, а ты его даже нигде не используешь.

       The realloc() function returns a pointer to the newly allocated memory...

Твоя конструкция вообще избыточна, достаточно только realloc() и всё.

И да, GNU кодинг сайтл портит кодеру карму.

mashina ★★★★★
()

Хм, а при x = 1 вызовется realloc которому предложат изменить размер на такой же, что уже выделен ?

roy ★★★★★
()

Вот ошибка:

realloc (info.bios_info->characteristics, (sizeof(char*) * x));
[/quote]
Указатель-то не изменяется, надо так делать:

info.bios_info->characteristics =realloc (info.bios_info->characteristics, (sizeof(char*) * x));
Eddy_Em ☆☆☆☆☆
()

Где проверка возвращаемого значения от realloc()?

JackYF ★★★★
()
Ответ на: комментарий от Eddy_Em

А вообще, лучше память блоками выделять и делать realloc лишь когда блок полностью заполнен.

Например:

ssize_t mygetline(char **buffer, int fd){
	size_t bufportion = 16000, bufsz = bufportion, i = 0;
	free(*buffer); *buffer = NULL;
	char *ptr;
	char *buf;
	buf = malloc(bufsz);
	if(!buf){freeQS(); die(MEMERR);}
	ptr = buf;
	if(read(fd, ptr, 1) != 1){ free(buf); return -1; }
	do{
		if(*ptr == '\n' || *ptr == 0) break;
		ptr++;
		if(++i >= bufsz){
			bufsz += bufportion;
			buf = realloc(buf, bufsz);
			if(!buf){freeQS(); die(MEMERR);}
			ptr = &buf[i];
		}
	}while(read(fd, ptr, 1) == 1);
	*ptr = 0;
	if(ptr > buf && *(ptr-1) == '\r') *(ptr-1) = 0;
	*buffer = strdup(buf);
	free(buf);
	return strlen(*buffer);
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от mashina

потому что x будет мало, вроде очевидно почему.

А вообще, лучше память блоками выделять и делать realloc лишь когда блок полностью заполнен.

Ему в прицнипе вообще realloc() не нужен, достаточно сразу иметь массив на 32 указателя.

mashina ★★★★★
()
Ответ на: комментарий от mashina

Понятно, что в текущей редакции вообще надо malloc вынести из цикла и получится коротенькая запись.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Это 3.1415здец, а не код. Про нечитабельность и отсутствие пробелов после if, do ... я уже молчу.

ssize_t mygetline(char **buffer, int fd){
..
	free(*buffer); *buffer = NULL;

За это за яйца подвешивать. Если кто-то кроме тебя захочет воспользоваться этой функцией, то он 100% словит segfault.

	buf = malloc(bufsz);

лишнее. достаточно выставить buf = 0 и bufsz = 0. это уменьшит код и увеличит читабельность, а работать всё будет также как и раньше

Reset ★★★★★
()
Ответ на: комментарий от Reset

Если кто-то кроме тебя захочет воспользоваться этой функцией, то он 100% словит segfault.

Точно, надо проверить на !NULL buffer, а потом уже делать free(*buffer).

достаточно выставить buf = 0 и bufsz = 0. это уменьшит код и увеличит читабельность

В принципе - да.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Reset

Про нечитабельность и отсутствие пробелов после if, do ... я уже молчу.

Терпеть не могу пробелы в этих местах. И читабельность лично для меня - наилучшая.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Точно, надо проверить на !NULL buffer, а потом уже делать free(*buffer).

нет, нет, нет ! тут вообще не надо делать free

Reset ★★★★★
()
Ответ на: комментарий от Reset

Надо, иначе утечка памяти будет. А если выкинуть malloc, то и сегфолт может быть (мы-то не знаем размер буфера).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Надо, иначе утечка памяти будет.

Не будет. За память должен отвечать пользовательский код. Если пользователь передает тебе уже аллоцированный кусок, то он ССЗБ. Нелокальность при выделении/освобождении памяти это то за что надо вешать за яйца.

А если выкинуть malloc, то и сегфолт может быть (мы-то не знаем размер буфера).

Да, еще надо убрать read перед do. И чуть-чуть преобразовать первые две строки цикла. Кстати, только что увидел - read(, , 1) это 3.1415здец. Используй fread, или читай бОльшими кусками.

Reset ★★★★★
()
Ответ на: комментарий от Reset

Я и собираюсь переделать эту функцию, чтобы читать большими кусками и обрабатывать их. А остатки - «впихивать» обратно в stdin.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Естественно. Но если не было копии указателя на info.bios_info->characteristics, то память уже не освободить.

AptGet ★★★
()
Ответ на: комментарий от Eddy_Em

Я вообще склоняюсь к отказу от непосредственного использования malloc/calloc/realloc и free в коде. Вместо них лучше использовать макросы:

#define _ALLOC(ptr, size, type)  do{free(ptr); ptr = calloc(size, sizeof(type)); if(!ptr) RETMACRO;}while(0)
#define _FREE(ptr) do{free(ptr); ptr = NULL;}while(0)
А макрос RETMACRO определить как return, ну а в функциях, где поведение другое, переопределять. Например:
type function(args){
type *ret;
#undef RETMACRO
#define RETMACRO do{ret = NULL; goto free_all;}while(0)
…
free_all:
    _FREE(ptr1);
    _FREE(ptr2);
    return ret;
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Reset

Не будет. За память должен отвечать пользовательский код. Если пользователь передает тебе уже аллоцированный кусок, то он ССЗБ. Нелокальность при выделении/освобождении памяти это то за что надо вешать за яйца.

во всем нужно по ситуации смотреть вчера кучу времени убил на это чудо

DWORD WINAPI GetPrivateProfileSection(
  __in   LPCTSTR lpAppName,
  __out  LPTSTR lpReturnedString,
  __in   DWORD nSize,
  __in   LPCTSTR lpFileName
);

Parameters

lpAppName

    The name of the section in the initialization file.

lpReturnedString

    A pointer to a buffer that receives the key name and value pairs associated with the named section. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.

nSize

    The size of the buffer pointed to by the lpReturnedString parameter, in characters. The maximum profile section size is 32,767 characters.

lpFileName

    The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return value

The return value specifies the number of characters copied to the buffer, not including the terminating null character. If the buffer is not large enough to contain all the key name and value pairs associated with the named section, the return value is equal to nSize minus two.
если интересно загуглите суть ее такова что она возвращает массив одним куском выделенный в котором такой формат key=value\0key=value\0key=value\0\0 каждый новый кодер должен трах*** с этим массивом кстати еще проблема узнать нужный размер буфера а то она просто обрежет и половину настроек не вернет и вот каждый кто пользуется вынужден трах**** а можно было бы сделать что бы парсила она сама строила вектор указателей на key=value и возвращала указатель char** ВСЕ и предоставить вторую функцию для освобождения памяти

выглядело бы это так

char** p = GetPrivateProfileSection(...);
...
FreePrivateProfileSection(p);
очень удобно а сейчас же это трах*** мало того что пишеш каждый раз мини парсер дак еще и размер буфера незнаеш какой ей передать есть костыльный способ узнать но про него и говорить стыдно

anonymous
()
Ответ на: комментарий от Eddy_Em

за такое бить по печени надо ты пойми что твой код будут читать другие не знакомые с твоими макросами и нихуя непонятно будет такое можно юзать еслди только код никому не будеш показывать

anonymous
()
Ответ на: комментарий от Eddy_Em

если все участники проекта знают что это за макросы или это известные макросы типа g_return_if_fail то прекрасно но если это отсебятина про которую знаеш ты один то будь любезен не показывай этот код никому тем более на форуме

anonymous
()
Ответ на: комментарий от anonymous

В совместном проекте никто не мешает более прилично оформить эти макросы. А когда я «быдлокодю» свои велосипеды, мне как-то плевать, как макросы называются - лишь бы они работали и мне меньше надо было одно и то же набирать.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Во-первых, у меня с английским плохо (с точки зрения русский->английский). Во-вторых, я не виноват, что гугл отображает файлы без прогона их через enconv.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Во-первых, у меня с английским плохо
Бывает и хуже.

русский->английский

Неправильный подход. Нужно думать сразу на английском.

Во-вторых, я не виноват, что гугл отображает файлы без прогона их через enconv.

А вот тут твоя вина, что ты не используешь utf-8.

anonymous
()
Ответ на: комментарий от anonymous

А вот тут твоя вина, что ты не используешь utf-8

Может, лет через 10 задумаюсь: а не перейти ли мне на юникод? Или позже, когда старческий маразм свалит.

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.