когда надо malloc, а когда нет - c программированием - PullRequest
0 голосов
/ 29 сентября 2011

У меня мало вопросов относительно того, когда использовать malloc или в этом случае strdup.
Ниже приведена небольшая функция, которую я украл из Интернета.
Я пытаюсь понять код, но застрял снесколько проблем.
1. код присвоил значение psrc и pdest.пример

char* psrc = dups;  
char* pdest = s;  

Сомнение: нам не нужно использовать malloc для выделения места для psrc и pdest.?Если нет, то почему.

  1. pdest [0] = '\0'; Приведенная выше строка выделяет символ завершения в начале строки pdest.тогда ранее почему мы присвоили pdest на s.пример char* pdest = s;?

Любая помощь или критика будет полезна для меня.Спасибо и всего наилучшего, Сэм

 char* deldupchars (char* s)    
 {      
   char* dups = strdup (s);      
   if (dups)     
   {      
    char* psrc = dups;      
    char* pdest = s;      
    char ch;      

    pdest [0] = '\0';      
    while ((ch = *psrc++) != '\0')    
    {            
     if (! strchr (pdest, ch))    
     {           
       *pdest++ = ch;           
     }             
    }       
    pdest [0] = '\0';      
    free (dups);       
   }      
   return s;       
 }       

Ответы [ 7 ]

1 голос
/ 29 сентября 2011
char* psrc = dups;      

Нет необходимости выделять здесь, поскольку dups было выделено strdup.

char* pdest = s;

Нет необходимости выделять здесь, поскольку s было выделено вызывающим.

pdest[0] = '\0';

Это записывает содержимое строки.Присвоение pdest = s назначает указатели, но не содержимое.

0 голосов
/ 29 сентября 2011
#include <stdio.h>

size_t undup (char *str);
size_t undup (char *str)
{
size_t src, dst;

for (src=dst=0; str[dst] = str[src++] ; ) {
  if (str[dst] != str[src] ) dst++;
  } 
return dst;
}

int main (int argc, char **argv)
{

  printf ("Before:%s\n", argv[1] );
  (void) undup ( argv[1] );
  printf ("After:%s\n", argv[1] );

  return 0;
}
0 голосов
/ 29 сентября 2011
  1. У вас там нет присвоения значения, но есть указатели. Это означает, что psrc указывает на ту же ячейку памяти, что и dups. Если вы хотите скопировать содержимое этой области памяти, вам нужно выделить память, а затем скопировать. (malloc + memcpy)
  2. pdest [0] = '\0'; - здесь не выделено. Это просто помещает нулевой терминатор в начало массива, на который он указывает. char* pdest = s; сделал pdest, указывающий на ту же память, что и s.
0 голосов
/ 29 сентября 2011

1) То, что вы получаете в psrc и pdest - это не более чем другой указатель на строку символов. Это не значит, что у вас есть 2 строки символов, но два указателя на одну строку. Строка не дублируется. Вам не нужно выделять psrc и pdest , потому что компилятор уже выделяет память для этих переменных, когда вы объявляете их (точно так же, как вам не нужно выделять память для int , например). Это просто 32-разрядные целые числа без знака (то есть для 32-разрядных систем).

2) pdest используется, чтобы не изменять исходное значение s, так как pdest изменяется внутри цикла while. Опять же, строка НЕ ​​дублируется, так что на самом деле pdest модифицирует строку, указанную s.

0 голосов
/ 29 сентября 2011

strdup выполнит внутри него malloc и вернет выделенную память (поэтому вам нужно вызвать free (dups) в конце функции).

pdest / psrc - это просто указатели (то есть:просто ссылается на память, которая была ранее выделена из 's', а позже используется для обхода в этой выделенной памяти).Я думаю, что главная путаница заключается в том, что указатели - это просто: они указывают на адрес в памяти - так что вы можете иметь много указателей на один и тот же адрес памяти, и вы можете использовать этот указатель для перемещения - в памяти, ранее размещенной в malloc'е.).

См .: http://www.mkssoftware.com/docs/man3/strdup.3.asp

0 голосов
/ 29 сентября 2011

strdup() malloc() s - память для строки, поэтому вы можете сохранить через указатель, который возвращает strdup().Но вам нужно free() той памяти, которую вы правильно делаете.

Со страницы руководства strdup():

Функция strdup() возвращает указатель на новую строкукоторый является дубликатом строки s.Память для новой строки получается с помощью malloc(3) и может быть освобождена с помощью free(3).

0 голосов
/ 29 сентября 2011

Нам не нужно выделять память для dups, потому что оператор char * psrc = dups не копирует то, на что указывает dups, а только куда он указывает. Это означает, что выделение в strdup достаточно для обоих указателей

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