|
0 / 0 / 0
Регистрация: 05.11.2023
Сообщений: 4
|
|||||||||||
Почему происходит утечка памяти?05.11.2023, 18:56. Показов 1262. Ответов 11
Я пытался написать функцию для конкатенации 2 строк. При этом к одной строке можно было бы повторно присоединять еще строки и при это не было утечки памяти. В итоге добился того что утечки памяти нет, но не совсем понимаю почему в 1 варианте её нет, но во 2 она появляется? Проверял с помощью valgrind --leak-check=full.
==23495== definitely lost: 9 bytes in 1 blocks
0
|
|||||||||||
| 05.11.2023, 18:56 | |
|
Ответы с готовыми решениями:
11
Почему возникла утечка памяти Вектор, утечка памяти, функция создания и выделение памяти Утечка памяти |
|
Вездепух
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
|
|
| 05.11.2023, 19:52 | |
Сообщение было отмечено MidnightUser как решение
Решение
1
|
|
|
Заблокирован
|
||||||
| 05.11.2023, 21:34 | ||||||
0
|
||||||
|
2487 / 1151 / 709
Регистрация: 25.04.2016
Сообщений: 3,310
|
|||||||||||
| 05.11.2023, 22:31 | |||||||||||
ну и если у нас копирование происходит несколько раз, мы каждый раз пропускаем его через проверку:
URUSOFF, if (!*str1) означает if(!str1[0]) вы уверены, что вам именно это нужно? ошибка кроется, во-первых, в проверке выделения памяти realloc'ом, поскольку программа просто сообщает, что память не была выделена, а дальше как ни в чем ни бывало копирует данные, даже если там нулевой указатель. Во-вторых memcpy тоже возвращает указатель и его тоже надо проверять. И в-третьих, запрос памяти происходит внутри функции, а realloc может просто выделить новый блок памяти и вернуть указатель уже на этот новый блок памяти, и в этом случае адрес str1, переданный в функцию, становится бесполезен, т.е. нам нужно не только записать результат realloc в temp, но потом еще и вернуть этот temp в main, чтобы мы не потеряли адрес выделенного realloc'ом блока памяти. И это еще без учета возможных ошибок malloc'а в main и возможных ошибок ввода, проверок которых в коде просто нет. Сюда подкинем еще пару ошибок размера данных, ведь и realloc, и memcpy ждут количество байт в качестве размера, а char далеко не всегда и не везде равен одному байту. И только после всего этого мы получаем примерную картину происходящего. Тут ошибки практически в каждой второй строчке, просто удивительно как оно вообще запускалось.
0
|
|||||||||||
|
Вездепух
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
|
|||
| 05.11.2023, 22:35 | |||
memcpy четко говорит, что возвращаемый указатель всегда равен переданому. Никогда нет смысл проверять результат memcpy. Проверять надо до.char по определению. Поэтому char всегда и везде равен одному байту. Никаких ошибок размера данных из-за этого в этом коде нет. realloc и memcpy ждут количество char в качестве размера.По этой причине умножение на sizeof(char) при выделении памяти - бесполезное и ненужное действие. Это не ошибка, но и смысла в этом нет, ибо sizeof(char) всегда и везде гарантированно по определению равно 1.Странно, что эта разобранная вдоль и поперек тема по-прежнему вызывает затруднения.
0
|
|||
|
2487 / 1151 / 709
Регистрация: 25.04.2016
Сообщений: 3,310
|
||
| 05.11.2023, 23:13 | ||
|
Как по мне, лучше уж перебдить. Хуже точно не будет. На счет того, что char всегда равен одному байту, нет не всегда, мне пару раз попадались двухбайтные чары. Гарантируется что char <= short, однако не припоминаю, чтобы гарантировалось, что он всегда равен одному байту. Так что, на мой взгляд смысл есть.
0
|
||
|
Вездепух
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
|
|||
| 05.11.2023, 23:42 | |||
memcpy это никак не относится. К чему вы это упомянули?char может состоять и из двух, и из четырех и из сколько угодно "байтов". Однако в языках С и С++ минимальной атомарной единицей измерения памяти является char. В С и С++ байтом является именно char. sizeof, malloc, realloc и все остальное работают именно в единицах char, а не в ваших "байтах". То есть sizeof(char) всегда гарантированно равно 1. И о том, сколько там у вас в реальности "байтов" прячется в char никогда беспокоиться не нужно.Если у вас char состоит из 100 "байтов", то malloc(1) будет выделять именно 100 таких "байтов".
0
|
|||
|
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,870
|
||||||
| 06.11.2023, 00:54 | ||||||
|
Можно вставлю?
А кто за вас будет возвращать указатель на новый блок памяти из функции.? Молодые люди....
и возвращает на него указатель....
0
|
||||||
|
2487 / 1151 / 709
Регистрация: 25.04.2016
Сообщений: 3,310
|
|||||||||||||
| 06.11.2023, 02:56 | |||||||||||||
|
TheCalligrapher, я понял о чем вы, но я имел в виду немного другое.
Посмотрите на код ТС. В функции main, он запрашивает память под массивы: Он вдруг вспомнил, что единицей измерения является char? Да ничего подобного. Он элементарно не учел, что и realloc, и memcpy ждут размер в байтах. И то, что это все заработало - это чистой воды везение, поскольку конкретно в этой программе используется массив чаров. Если бы использовался массив любого другого типа, уже была бы ошибка. По поводу возвращаемого значения memcpy я имел в виду вот это:
ablex, оставьте свои фантазии при себе. У вас богатое воображение, не спорю, однако здесь оно как-то вообще не к месту.
0
|
|||||||||||||
|
Вездепух
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
|
|||
| 06.11.2023, 05:15 | |||
malloc и realloc. Как будто два разных человека писало. В одном месте умножено на sizeof(char), а в другом - нет. Это действиельно странно.Но разница эта - чисто холиворно-стилистическая: sizeof(char) везде и всегда равно 1, поэтому от того, умножите вы на него или нет, ничего не изменится. Кто-то предпочитает умножать - чтобы везде было единообразно, независимо от конкретного sizeof. Кто-то наоборот, старательно избегает умножения на заведомую 1.(Я лично принадлежу к первой группе, то есть везде единообразно умножаю на размер типа. Но при этом я всегда стремлюсь делать p = malloc(n * sizeof *p), то есть мой код абстрагирован от имен конкретных типов.)Так что действительно, тут есть к чему придраться. Но ошибки здесь все равно нет. memcpy.
0
|
|||
|
0 / 0 / 0
Регистрация: 05.11.2023
Сообщений: 4
|
|
| 06.11.2023, 10:44 [ТС] | |
|
По поводу "качества" своего кода, скажу, что я пытался сделать так, чтобы это работало и найти рабочую логику решения, проверки на выделенную память в моем коде остались от другого кода из интернета, как и использование realloc, тоже оттуда же, я гуглил про размер char, поэтому не стал исправлять. С памятью работаю совсем недавно, обрабатывать ее особо не умею, да. Если есть гайд, то скиньте пожалуйста. Опять же топик в "C для начинающих" , с чего такая агрессия... За помощь, спасибо.
0
|
|
|
2487 / 1151 / 709
Регистрация: 25.04.2016
Сообщений: 3,310
|
||||||||||||||||||||||||||||||||||||||||||||
| 06.11.2023, 16:05 | ||||||||||||||||||||||||||||||||||||||||||||
К новичкам это никакого отношения не имеет. А я и правда выразился обобщенно и из-за этого не совсем корректно, так что возникшие у TheCalligrapher вопросы вполне закономерны.Ну а что касается вашего кода Там вот выше есть пример того как это делается с учетом всех запятых, проверок и прочего. Просто сравните со своим кодом. MidnightUser, malloc, calloc и realloc могут вернуть нулевой указатель в случае, если память не была выделена, и это всегда нужно учитывать. Кроме того, malloc, calloc, realloc, memcpy, memmove и прочие функции, работающие с памятью, ждут не количество элементов массива, а либо объема в байтах, либо числа элементов массива и объема отдельного элемента в байтах, и это тоже нужно учитывать. Ну и если вы что-то делаете с размером массива в функции, то всегда стоит возвращать указатель на получившийся массив, поскольку внутри функции собственное пространство имен. Добавлено через 1 час 57 минут MidnightUser, допустим, вы в main создаете массив:
К счастью, существует функция atexit(), которая регистрирует некоторую другую функцию, например my_function, которая вызывается при завершении программы. Эта функция всегда объявляется как void name_function (void) и вызывается она вне зависимости от того как именно была завершена программа, был ли это return в main или exit в другой функции, вызванной из main:
Это один момент. Другой момент касается realloc внутри другой функции, например:
int *a в main - это одна переменная, а вот int *a в my_function - это уже другая переменная, которая существует только пока работает функция my_function. И если мы каким-то образом изменим значение a внутри my_function, то оно изменится только внутри my_function, а в main значение a так и останется прежним, поэтому мы делаем следующее:
1
|
||||||||||||||||||||||||||||||||||||||||||||
| 06.11.2023, 16:05 | |
|
Помогаю со студенческими работами здесь
12
Утечка памяти Утечка памяти в free() Будет ли утечка памяти? Утечка памяти в функции Генератор случайного пароля. Утечка памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|
Фото: Daniel Greenwood
kumehtar 13.11.2025
|
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга,
Ты же видел моря и метели.
Как сменялись короны и стяги,
Как эпохи стрелою летели.
- Этот мир — это крылья и горы,
Снег и пламя, любовь и тревоги,
И бескрайние. . .
|