Вопрос по c, free – Освобождение строк в Си

8

Если бы я написал:

<code>char *a=malloc(sizeof(char)*4);
a="abc";
char *b="abc";
</code>

мне нужно освободить эту память, или это сделано моей системой?

Да, unichar - это символ Unicode, но концепция не является специфичной для target-C. В целом, не стоит делать предположения о размере структур данных. ThomasW
Еще один комментарий состоит в том, что я считаю, что вам не нужен sizeof (char), поскольку во всех реализациях, которые я видел до сих пор, всегда 1 байт. So malloc (4); будет достаточно Lefteris
@ThomasW Боюсь, я не уверен, что именно Unichar, но я предположил, что это связано с Unicode. Быстрый поиск в Google предлагает target-c, который является другим языком: P Но любые символы Юникода обычно не называют просто char. Возьмите широкие символы wchar_t, например. Хотя может быть неправильно, но это то, что я видел до сих пор с реализациями, с которыми я имел дело Lefteris
@Lefteris на самом деле вышеприведенная реализация хороша. Хотя в большинстве систем используются однобайтовые символы, приведенная выше реализация не дает понять, что выделяется, и если код изменяется на использование unichars, которые обычно составляют два байта, его будет легче изменить. ThomasW

Ваш Ответ

4   ответа
4

a="abc"вы не заполняете только что выделенную память, вы переназначаете указатель, указывающий на статическую строку "abc".b указывает на одну и ту же статическую строку.

То, что вы хотите вместо этого,strncpy(a, "abc", 4), который будет копировать содержимое "abc" в память, которую вы распределили (чтоa указывает на).

Тогда вам нужно будет освободить его, когда закончите.

2

Конкретный ответ:

char *a=malloc(sizeof(char)*4);

Вы выделяете память, чтобы освободить ее.

a="abc";

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

использованиеstrcpy(a,"abc"); вместоa="abc"; переместить строку в выделенную память.

strcpy является корнем многих переполнений буфера. Вместо этого используйте strncpy.
11

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

Попробуйте это:

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

int main()
{
  char *a=(char*)malloc(sizeof(char)*4);
  printf("Before: %p\n",a);
  a = "abc";
  printf("After: %p\n",a);
  free(a);
  char *b = "abc";

  return 0;
}

Вы получите

Before: 0x100100080
After: 0x100000f50

Вы увидите, что два указателя разные. Это потому что строковый литерал"abc" помещается в сектор данных двоичных файлов и когда вы делаете

a = "abc"

вы меняете указательa указывать на постоянную литеральную строку"abc" и вы теряете ранее выделенную память. призваниеfree наa больше не является правильным, просто потому, что он больше не будет указывать на действительный динамически назначенный адрес. Чтобы сохранить указатель и иметь возможность освободить его, вы должны скопировать строку с

strncpy(a, "abc", 4)

Это будет эффективно копировать символы из литерала в динамически размещенный метод, сохраняя исходный указатель.

Вы правы, я только рассматривал этот конкретный случай, позвольте мне отредактировать его
@Lefteris Это вообще не проверяется,strcpy будет копироватьstrlen(source) не заботясь о размере места назначения. Если длина источника & gt; dest длина, то он будет писать за пределами.
strcpy является корнем многих переполнений буфера. Вместо этого используйте strncpy.
@rampion Просто из любопытства, почему ты так говоришь? Потому что strcpy копирует strlen (исходные) байты, которые не всегда могут быть проверены по размеру буфера назначения? Или я не так понимаю?
@Андна, конечно, если вы используетеstrncpy вам придется освободить память сfree(a) в конце кода.
3

Вы не можете назначить строку таким образом с C

a = "abc"

Однако, если вы используетеmalloc тогда вы должны использоватьfree, как это

free(a);

Но обратите внимание, если вы используетеfree(a) в вашем примере вы получаете ошибку. Потому что послеmalloc вы меняете указательa значение статической строки"abc"; So the next free(a) попробуйте освободить статические данные. И вы получите ошибку.

Похожие вопросы