LINUX.ORG.RU

Хочется проследить выделение памяти


0

0

Написал прогу, где есть динамический массив (огромное спасибо eRazor-у).

По мере введения пользовательских данных выделяется по 3 байта.

Как в linux проследить выделение памяти этой прогой через консольные команды?

★★★★

Ещё один вопрос возник. Код в следующем сообщении.

Почему valgrid ругается на 32 строчку? Что не так в коде?:
$ valgrind ./short_to_long_chars
a-z
==3330== Invalid read of size 1
==3330== at 0x80484FF: main (short_to_long_chars2.c:32)
==3330== by 0x4026EC5B: __libc_start_main (in /lib/libc-2.3.2.so)
==3330== by 0x80483B0: (within /home/anton/c/short_to_long_chars)
==3330== Address 0x410D5027 is 0 bytes after a block of size 3 alloc'd
==3330== at 0x40029A55: malloc (vg_replace_malloc.c:153)
==3330== by 0x804847C: main (short_to_long_chars2.c:13)
==3330== by 0x4026EC5B: __libc_start_main (in /lib/libc-2.3.2.so)
==3330== by 0x80483B0: (within /home/anton/c/short_to_long_chars)
abcdefghijklmnopqrstuvwxyz
Allocated 3 bytes for user input
==3330==
==3330== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==3330== malloc/free: in use at exit: 0 bytes in 0 blocks.
==3330== malloc/free: 1 allocs, 1 frees, 3 bytes allocated.

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

#include <stdlib.h>

int main()
{
	static int numbers[9];//вывод цифр
	static int alphabet[25];//вывод букв
	int i,i2; //счётчики циклов
	int size_of_input; //кол-во введённых символов
	int interval_start, interval_end;//начало и конец интервала
	int to_allocate=3;//Порция выделяемой памяти
	int counter=0;//Счётчик, который следит за тем, сколько порций надо
	char c;//Временный ввод
	char* input=(char*)malloc(to_allocate); //ввод
	
	//Ввод
	for(i=0; ( c=getchar() )!='\n'; i++)
	{
		//Если нужна ещё порция памяти
		if( counter++ >= to_allocate )
		{
			to_allocate *= 2;
			input = (char*)realloc(input,to_allocate);
			counter = 0;
		}
		*(input+i) = c; //Записываем в переменную ввода из временного хранилища
	};
	size_of_input=i;
	
	//Обработка данных
	for(i=0; i<=size_of_input; i++)
	{
		if(*(input+i)=='-')
		{
			interval_start=input[i-1];
			interval_end=input[i+1];
			
			//Является ли интервал интервалом чисел?
			if( (input[i-1] >= '0' && input[i-1] <= '9') && (input[i+1] >= '0' && input[i+1] <= '9') )
			{
				for(i2=interval_start; i2<=interval_end; i2++) numbers[i2-'0']=i2;
			}else{
				for(i2=interval_start; i2<=interval_end; i2++) alphabet[i2-'a']=i2;
			}
		}
	}
	
	//Вывод
	for(i=0; i<=9; i++) printf("%c",numbers[i]);	
	for(i=0; i<=25; i++) printf("%c",alphabet[i]);
	
	printf("\nAllocated %d bytes for user input\n", to_allocate);
	
	free(input);
	
	return 0;
}

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

Уверен? ;-) Я дико извиняюсь, но строка counter=0; (Это внутри цикла где realloc) не нужна. Упс. Я говорил -- мне не на чем проверить (типа отмазываюсь). Соответственно counter можно вообще выкинуть и использовать i.

И я тебе говорил, строку

input = (char*)realloc(input,to_allocate);

надо заменить на

if( !(input = (char*)realloc(input,to_allocate)) ) { printf("Unable to allocate memory."); return 1; // или exit сюда вставь }

best regards..

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

У тебя ещё одна ошибка. В том блоке где ты поставил коментарий "Обработка данных" ты пробегаешь по всему массиву до конца в цикле: for(i=0; i<size_of_input; i++). При этом на каждой итерации получаешь адрес объекта равный "текущий указатель + 1": interval_end=input[i+1];. Чего делать нельзя т.к. ты используя этот адрес обращаешься к его содержимому. Либо сделай цикл до "последний элемент - 1" либо переделай код так, что бы не разименовывать указатель который указывает на элемент находящийся за последним элементом в массиве input. Лучше сделать первое : for(i=0; i<size_of_input-1; i++).

Если непонятно о чём я написал, подумай о том как будет программа работать если пользователь завершит вводимую строку символом '-'.

best regards..

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

Я понял, о чём ты написал. У меня как раз и не предусмотрена проверка на глупого пользователя. Программка-то всего-лишь учебная. Но я напишу более жёсткую проверку. Также, если поставить '-' вначале - возникнет seg. fault.

А valgrind действительно умолк, belive me.

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

А это ещё не всё ;-)

Ещё замечание. Так: (input[i-1] >= '0' && input[i-1] <= '9') проверять на то является символ цыфрой -- некорректно. Никто не гарантирует монотонное возрастание кодов символов (Не везде используется ASCII). Используй isdigit() для этого.

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

Далее, медитация над строкой: numbers[i2-'0']=i2; Здесь у тебя, допустим, i2 равно 15. В этом случае выражение (i2-'0') означает (15-код_символа_0_в_используемой_таблице_символов), что, наверняка, означает отрицательный индекс. Ошибка.

Вообще, нельзя в адресной арифметике полагаться на коды симолов.

Далее. В самом конце, где комментарий //Вывод. Там два цикла. Если ты имеешь длинну массива, то перебор всех элементов -- это использование диапазона от 0 до меньше длинна, т.е. [0;size) , а не от 0 до меньше или равно длинна, т.е. [0;size].

И ещё заданы неправильные длины массивов numbers и alphabet. Вместо 9 и 25 надо соответственно 10 и 26.

best regards..

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

А я говорю, не умолк. В том куске который я тебе с realloc кинул, я не подумав вписал обнуление counter при realloc, чего, естественно, делать не надо.

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

>В самом конце, где комментарий //Вывод. Там два цикла. Если ты имеешь длинну массива, то перебор всех элементов -- это использование диапазона от 0 до меньше длинна, т.е. [0;size) , а не от 0 до меньше или равно длинна, т.е. [0;size].

Всё-таки у меня всё правильно в этом месте. При < (а не <=) последняя буква и цифра не выводяться.

>И ещё заданы неправильные длины массивов numbers и alphabet. Вместо 9 и 25 надо соответственно 10 и 26.

Но почему же? от 0 до 9 - 10 фифр, от 0 до 25 - 26 букв от a до z.

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

Хы, действительно. При >=9байтах valgrid просто орал от негодования.

Спасибо тебе за ценные советы! Очень помог.

P/S Хотя на сабж никто так и не ответил.

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

>Но почему же? от 0 до 9 - 10 фифр, от 0 до 25 - 26 букв от a до z

Что почему???? Надо хранить 10 элементов? int numbers[9] создаёт массив для хранения девяти элементов. Девятка означает массив из ДЕВЯТИ элементов, а не массив, в котором поместяца цыфры от 0 до 9 :-)

>Всё-таки у меня всё правильно в этом месте. При < (а не <=) последняя буква и цифра не выводяться.

Слушай, повторяю последний раз :-) если ты создаёшь массив из n елементов: int arr[n] , то проход по всем элементам это цикл: for(int i=0;i<n;i++). Меньше, а не меньше и равно.

best regards..

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