Что не так с этим сегментом кода C? Когда я не назначаю т это работает нормально - PullRequest
1 голос
/ 17 октября 2019

Это ошибочный код.

#include <stdio.h>
#include<stdlib.h>
int main() {
    int* t = (int*) malloc(sizeof(int));
    int a = 4;
    t = &a;
    printf("%d\n",*t);
    free(t);
    return 0;
}

Как я могу это исправить?

Ответы [ 3 ]

2 голосов
/ 17 октября 2019

malloc и calloc используются для динамического выделения памяти для массивов. Как сказал Blaze в комментариях, простое удаление malloc решит вашу проблему:

#include <stdio.h>
#include<stdlib.h>
int main() {
    int* t;
    int a = 4;
    t = &a;
    printf("%d\n",*t);
    return 0;
}

Вам также не понадобится free, потому что вы не выделяли динамическую память. Более того, если вы создаете динамическую память для массива, я бы порекомендовал вам использовать calloc вместо malloc, так как в отличие от malloc, calloc инициализирует память с нуля.

1 голос
/ 17 октября 2019

Вообще говоря, для программы на Си доступно три типа памяти.

  • память для глобальных и статических переменных
  • "автоматическая" память для локальных переменных и параметров функций
  • динамическая память, которая выделяется самим программным кодом с использованием таких функций, какmalloc().

Автоматическая память (я называю это так, поскольку в C automatic было ключевое слово, которое вы могли использовать для его указания), автоматически выделяется из стека программ или из регистра ЦП. файл, когда функция вводится и автоматически освобождается при выходе из функции.

Динамическая память выделяется из «кучи», которая представляет собой просто кучу памяти, а не в каком-либо определенном порядке.

В вашем коде у вас есть автоматическое и динамическое распределение:

int* t = (int*) malloc(sizeof(int));

Этот код выделяет память для указателя на стек (t) и достаточно памяти для int из кучи. Указатель на эту память сохраняется в t

int a = 4;

Этот код выделяет память для int в стеке (a) и сохраняет в нем int 4.

t = &a;

Этот код получает указатель на a (который выделяется из стека) и сохраняет его в t.

Обратите внимание, что предыдущее содержимое t указателя на динамически выделенный блок памяти из кучи теперь потеряно. Теперь у вашей программы нет возможности освободить кучу памяти. Это называется утечкой памяти, и в более крупных программах ошибки такого рода приводят к тому, что использование памяти продолжает увеличиваться до тех пор, пока система не остановится или не произойдет сбой программы, поскольку она не может быть выделена для кучи памяти.

printf("%d\n",*t);

Это просто выводит то, на что указывает t, то есть a, что равно 4.

free(t);

free() используется библиотекой C для возврата памяти, которая была выделенаиз кучи обратно в кучу. К сожалению, t больше не указывает на память из кучи, он указывает на память в стеке. Вполне вероятно, что эта строка повреждает кучу. Если бы вы не собирались выходить из программы, это было бы катастрофой.

1 голос
/ 17 октября 2019

Вот что происходит в вашем коде:

Указатель t указывает на int, который создается динамически

int* t = (int*) malloc(sizeof(int));

Данные:

t -> INT

Новыйпеременная создана

int a = 4;

Данные:

t -> unnamed: integer
           a: 4

T присвоены

t = &a;

Данные:

    unnamed: integer
t->       a: 4

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

(пытается) освободить память

free(t);

Данные:

    unnamed: integer
t->       a: 4

Памятьне может быть освобожден, потому что он указывает на пространство стека (для в данном случае локальной переменной), а не на пространство кучи (для динамических переменных). См. Комментарий Джереми ниже.

Решение:

Не используйте malloc и free и присваивайте t (как указатель) переменной a после создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...