Утечка памяти в программе, которая считывает и выводит строку - C (СИ)
Формулировка задачи:
Есть вот такая простая программа, считывающая строку с клавиатуры и выводящая ее.
Программа рабочая, но valgrind находит утечку, хотя все освобождено
Программа (не эта, но с аналогичной проблемой, просто более громоздкая) должна пройти тестирование в специальной системе, так что просто забыть о проблеме не вариант
Заранее спасибо за любые советы
Листинг программы
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- char* string =(char*)malloc(50*sizeof(char));
- int i = 0,
- N = 0;
- while((string[i] = getchar()) != EOF) {
- if(string[i] == '\n') N++;
- i++;
- }
- printf("%s\n", string);
- free(string);
- return 0;
- }
Решение задачи: «Утечка памяти в программе, которая считывает и выводит строку»
textual
Листинг программы
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- void LowerRegister(char** pStrings,int NN,char** pNewStrings)
- {
- if (!NN)
- {
- return;
- }
- for (int ii = 0; ii < NN; ++ii)
- {
- for (int jj = 0; true; ++jj)
- {
- int iChr = pStrings[ii][jj];
- if (iChr)
- {
- pNewStrings[ii][jj] = (char)(((iChr >= 'A') && (iChr <= 'Z')) ? iChr | 0x20 : iChr);
- }
- else
- {
- break;
- }
- }
- }
- }
- int main(int argc,char** argv)
- {
- const int MAX_STRING = 5;
- const int MAX_LENGTH = 5;
- char** pStrings = (char**)malloc(sizeof(char*) * MAX_STRING);
- if (!pStrings)
- {
- printf("\nErr: Memory error.\n");
- return 0;
- }
- memset(pStrings,0,sizeof(char*) * MAX_STRING);
- int ii = 0;
- int jj = 0;
- for (ii = 0; ii < MAX_STRING; ++ii)
- {
- pStrings[ii] = (char*)malloc(MAX_LENGTH + 1);
- if (pStrings[ii])
- {
- memset(pStrings[ii],0,MAX_LENGTH + 1);
- }
- else
- {
- for (jj = 0; jj < ii; ++jj)
- {
- if (pStrings && pStrings[jj])
- {
- free(pStrings[jj]);
- pStrings[jj] = NULL;
- }
- }
- if (pStrings)
- {
- free(pStrings);
- pStrings = NULL;
- }
- printf("\nErr: Memory error.\n");
- return 0;
- }
- }
- char** pNewStrings = (char**)malloc(sizeof(char*) * MAX_STRING);
- if (!pNewStrings)
- {
- printf("\nErr: Memory error.\n");
- return 0;
- }
- memset(pNewStrings,0,sizeof(char*) * MAX_STRING);
- for (ii = 0; ii < MAX_STRING; ++ii)
- {
- pNewStrings[ii] = (char*)malloc(MAX_LENGTH + 1);
- if (pNewStrings[ii])
- {
- memset(pNewStrings[ii],0,MAX_LENGTH + 1);
- }
- else
- {
- for (int jj = 0; jj < MAX_STRING; ++jj)
- {
- if (pStrings && pStrings[jj])
- {
- free(pStrings[jj]);
- pStrings[jj] = NULL;
- }
- }
- if (pStrings)
- {
- free(pStrings);
- pStrings = NULL;
- }
- for (jj = 0; jj < ii; ++jj)
- {
- if (pNewStrings && pNewStrings[jj])
- {
- free(pNewStrings[jj]);
- pNewStrings[jj] = NULL;
- }
- }
- if (pNewStrings)
- {
- free(pNewStrings);
- pNewStrings = NULL;
- }
- printf("\nErr: Memory error.\n");
- return 0;
- }
- }
- ii = 0;
- jj = 0;
- int NN = 0;
- int iChr = 0;
- while ((iChr = getchar()) != EOF)
- {
- if (iChr == '\n')
- {
- jj = 0;
- ++ii;
- ++NN;
- if (ii > MAX_STRING)
- {
- for (ii = 0; ii < MAX_STRING; ++ii)
- {
- if (pStrings && pStrings[ii])
- {
- free(pStrings[ii]);
- pStrings[ii] = NULL;
- }
- if (pNewStrings && pNewStrings[ii])
- {
- free(pNewStrings[ii]);
- pNewStrings[ii] = NULL;
- }
- }
- if (pStrings)
- {
- free(pStrings);
- pStrings = NULL;
- }
- if (pNewStrings)
- {
- free(pNewStrings);
- pStrings = NULL;
- }
- printf("\nErr: Too many strings.\n");
- return 0;
- }
- }
- else if (jj > (MAX_LENGTH + 1))
- {
- for (ii = 0; ii < MAX_STRING; ++ii)
- {
- if (pStrings && pStrings[ii])
- {
- free(pStrings[ii]);
- pStrings[ii] = NULL;
- }
- if (pNewStrings && pNewStrings[ii])
- {
- free(pNewStrings[ii]);
- pStrings = NULL;
- }
- }
- if (pStrings)
- {
- free(pStrings);
- pStrings = NULL;
- }
- if (pNewStrings)
- {
- free(pNewStrings);
- pNewStrings = NULL;
- }
- printf("\nErr: Too many symbols in the string.\n");
- return 0;
- }
- else
- {
- pStrings[ii][jj++] = (char)iChr;
- pStrings[ii][jj] = 0; // Ensure ASCIIZ
- }
- }
- LowerRegister(pStrings,NN,pNewStrings);
- for (ii = 0; ii < NN; ++ii)
- {
- printf("%s\n",pNewStrings[ii]);
- }
- for (ii = 0; ii < MAX_STRING; ++ii)
- {
- if (pStrings && pStrings[ii])
- {
- free(pStrings[ii]);
- pStrings[ii] = NULL;
- }
- if (pNewStrings && pNewStrings[ii])
- {
- free(pNewStrings[ii]);
- pNewStrings[ii] = NULL;
- }
- }
- if (pStrings)
- {
- free(pStrings);
- pStrings = NULL;
- }
- if (pNewStrings)
- {
- free(pNewStrings);
- pNewStrings = NULL;
- }
- return 0;
- }
Объяснение кода листинга программы
Этот код считывает строки из стандартного ввода до тех пор, пока не будет введено что-то, что не является символом строки. Затем он преобразует каждую строку в нижний регистр. Если вводится больше строк, чем есть в массиве, код выведет сообщение об ошибке и завершит работу. Если вводится строка, которая превышает максимально допустимую длину, код также выведет сообщение об ошибке и завершит работу. Код использует динамическое выделение памяти для хранения вводимых строк и преобразованных строк.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д