LINUX.ORG.RU

*** glibc detected *** free(): invalid next size (fast): 0x0804a028 ***


0

0

Пишется ЯДЕРНЫЙ МОДУЛЬ.
Вообщем надо было реализовать склеивание двух строк char*. 
Написал пару функций, одна непосредственно для соединения, 
вторая оперирует первой в зависимости от параметров.
Запускаю, смотрю вывод, и вижу в нём вместе с исходными 
элементами мусор, по типу символо: " ! , и  др.
Решил вынести всё это в отдельный сишник и разобраться.
Определился глюк такого плана. Выглядит это так:

12
123
1234
12345
123456
1234567
12345678
123456789
12345678910
1234567891011
*** glibc detected *** free(): invalid next size (fast): 0x0804a028 ***
Aborted

Код такой:

#include <stdio.h>
#include <stdlib.h>

char *out = NULL;

char *addstr(char *first, char *second)
{
	int i, k, len_first, len_second;
	char *ret;

	if(!first) return 0;
	if(!second) return 0;
	k = 0;
	len_first = strlen(first);
	len_second = strlen(second);
	ret = malloc(sizeof(char[len_first + len_second]));
	
	for(i = 0; i < len_first; i++)
	{
		ret[i] = first[i];
	}
	for(i = len_first; i < (len_first + len_second); i++)
	{
		ret[i] = second[k];
		k++;
	}
	printf("%s\n",ret);
	return ret;
}

int netfw_add_to_out(char *a, char *b)
{
	char *temp;
	if(a  == 0)
	{
		temp = addstr(out,b);
		if(!temp) return 0;
		if(out) free(out);
		out = malloc(sizeof(char[strlen(out)+strlen(b)]));
	}
	else if(a != 0)
	{
		temp = addstr(a,b);
		if(!temp) return 0;
		if(out) free(out);
		out = malloc(sizeof(char[strlen(a)+strlen(b)]));
	}
	out = strcpy(out,temp);
	free(temp);
	return 0;
}

int main(int argc, char *argv[])
{
	netfw_add_to_out("1","2");
	netfw_add_to_out(0,"3");
	netfw_add_to_out(0,"4");
	netfw_add_to_out(0,"5");
	netfw_add_to_out(0,"6");
	netfw_add_to_out(0,"7");
	netfw_add_to_out(0,"8");
	netfw_add_to_out(0,"9");
	netfw_add_to_out(0,"10");
	netfw_add_to_out(0,"11");
	netfw_add_to_out(0,"3");
	netfw_add_to_out(0,"4");
	netfw_add_to_out(0,"5");
	netfw_add_to_out(0,"6");
	netfw_add_to_out(0,"7");
	netfw_add_to_out(0,"8");
	netfw_add_to_out(0,"9");
	netfw_add_to_out(0,"10");
	netfw_add_to_out(0,"11");
	printf("out = %s\n",out);
	
	return EXIT_SUCCESS;
}

Начал изучать. Одиннадцать вызовов netfw_add_to_out не случайны,
если их меньше, то такой ошибки нет, в модуле ошибка проявляется
в зависании всей системы, видимо сегфолт. И вот что интересно,
если закоментировать if(out) free(out) в этом куске:

	if(a  == 0)
	{
		temp = addstr(out,b);
		if(!temp) return 0;
	//	if(out) free(out);
		out = malloc(sizeof(char[strlen(out)+strlen(b)]));
	}

То глюк пропадает, но при этом, если я правильно понял, будет засорятся
память. Это подтверждается, если вызовов указанной выше функции будет 22.
Вот что выходит:

12
123
1234
12345
123456
1234567
12345678
123456789
12345678910
1234567891011
12345678910113
123456789101134
1234567891011345
12345678910113456
123456789101134567
1234567891011345678
12345678910113456789
12345678910113456789!10
12345678910113456789!1011
out = 12345678910113456789!1011

Как видно на последних трёх строчках появились "!", но они ни разу не указывались,
проверял несколько раз поиском :) их нет, значит это ошибка с выделением памяти.
Как я уже сказал, это если указанная выше строчка закоментирована, без комента
будет уже описанная ошибка *** glibc detected ***.

Вот собсно и вопрос - что не так и что делать!?

P.S. КОД ПИШЕТСЯ ДЛЯ МОДУЛЯ ПОЭТОМУ СТОРОННИЕ ЛИБЫ НЕ ПРИМЕНИМЫ!!!

Заранее спасибо!!!
★★★★★

>sizeof(char[len_first + len_second]))

увидел это и желание помогать исчесзло,
купи себе книжку по C, почитай ее, а потом пиши что-нибудь.

anonymous
()

это ядерный модуль?

может действительно выучить С сначала?

например add_str, открой для себя strcpy,
и ноль кто будет дописывать в конец?

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

> увидел это и желание помогать исчесзло,

пардон а что не так, мне нужен размер массива char содержащего len_first + len_second элементов

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

> например add_str, открой для себя strcpy,

читал ман по этой функции но так и не понял как копировать строку в конец исходной

а ноль в конце результирующей строки от второй строки сохраняется

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

Что-то я не понял. "размер массива char содержащего len_first + len_second элементов" это не (len_first+len_second)*sizeof(char)? А то что ты написал... И программа при этом не падает в кору? Странно, странно.

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

просто
1)sizeof не нужен, достаточно malloc(len_first+len_second)
2)еще правильнее добавить один 1 для нуля

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

strcpy может заменить твои циклы, а есть еще strcat, это как раз то что тебе нужно,
в общем info libc

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

Ну даже если sizeof(char)*(len_first+len_second) всёравно та же трабла, а потом, с чего компилятор не ругается на мой вариант, может так тоже можно.

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

твоя фунцкция выглядет примерно так:

char *add_str(const char *s1, const char *s2)
{
char *res;

res=malloc(strlen(s1)+strlen(s2)+1);
strcpy(res, s1);
strcat(res, s2);

return res;
}

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

	char *ret;

	ret = malloc(sizeof(char)*(strlen(first)+strlen(second)+1));
	strcpy(ret, first);
	strcat(ret, second);

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

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

Ну даже пусть если равен, но факт есть факт ошибка таже.
Вот попробовал так:

int netfw_add_to_out(char *a, char *b)
{
	char *temp;
	if(a  == 0)
	{
		temp = malloc(sizeof(char)*(strlen(out)+strlen(b)+1));
		temp = strcat(out,b);
//		temp = addstr(out,b);
		if(!temp) return 0;
		if(out) free(out);
		out = malloc(sizeof(char)*(strlen(out)+strlen(b)));
	}
	else if(a != 0)
	{
		temp = malloc(sizeof(char)*(strlen(a)+strlen(b)+1));
		temp = strcat(a,b);
//		temp = addstr(a,b);
		if(!temp) return 0;
		if(out) free(out);
		out = malloc(sizeof(char)*(strlen(a)+strlen(b)));
	}
	out = strcpy(out,temp);
	free(temp);
	return 0;
}


теперь оно сегфолтится, заменил addstr просто strcat.

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

ну ты хоть думай иногда,

вот ты сделал

free(out);

в следущей строчки ты делаешь strlen(out)

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

да и у ядра есть документ описывающий стиль кодирования,
советую ознакомиться.

anonymous
()

Будем надеяться, что Линус твой модуль в официальную ветку не примет. А то придётся срочно подключаться к Hurd team.

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

> "Это просто праздник какой-то!.."

ну это я уже просто теряюсь, т.е. то что это неправильно я понял и верну назад но выше указанная функция склеивающая строки не пашет.

cyclon ★★★★★
() автор топика

Мать ахтунг то какой, а где ваш мега-проект можно посмотреть ? :)

А то такой цирк, а по кусочкам не интересно.

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

> "Это просто праздник какой-то!.."

ну это я уже просто теряюсь, т.е. то что это неправильно я понял и верну назад но выше указанная функция склеивающая строки не пашет.

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

Анекдоты на С в виде моего модуля намечаются на середину, ну может даже и начало августа, вашему вниманию будут предложены шутки и анекдоты в моём исполнение, а так же различные шарады с призами и подарками :)

Пы.Сы. ошибка вроде как решилась, описАлся я =)

cyclon ★★★★★
() автор топика

А в чём глубинный смысл данных анекдотов ? Или это очередной лисапед с квадратными колёсами ?

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

Ну то что это очередной лисапед, это факт, в силу невежества предпологаю что только второй, но с треугольными колёсами.

cyclon ★★★★★
() автор топика

нда, парень, ты действительно циклон! :)

vilfred ☆☆
()

/me восхищён деятельностью товарища cyclon! У него есть возможность галопом до августа проскакать по граблям, на которые у многих комментаторов ушёл не один год (у меня, например, тоже).

ЗЫ Открывается клуб любителей cyclon. Основная идея движения - формализация новой методологии экспресс-обучения и решения практических задач с использованием фррумов a-la LOR. cyclon с момента создания - почётный член клуба

Искренне ваш...

anonymous
()

Хех, как исправлять я не знаю, но знаю, что это проявляется лишь в glibc с какой-то из версий новых. Слышал, что там теперь добавили механизм отслеживающий некоторые ошибки и сообщающий о них.

Поэтому и glibc detected =)

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