2016-05-15 2 views
-1

В моей программе я создал пару функций. В моем классе «void dstring_truncate (DString * destination, unsigned int truncatedLength);» Я неправильно распределяю память. Как правильно распределить память? Также возник вопрос о realloc и malloc. В чем разница между ними?Выделение памяти (C)

Заголовок файла

#ifndef DSTRING_H 
#define DSTRING_H 
#include <stdio.h> 

typedef char* DString; 

/* Returns a string that contains the same text as 'str'. The returned string is dynamicilly allocated */ 
DString dstring_initialize(const char* str); 

/* Puts the original string with source */ 
int dstring_concatenate(DString* destination, DString source); 

/* shortening *destination so it contains only truncatedLength number of sign. If 'truncatedLenght' is longer than string length nothing happens */ 
void dstring_truncate(DString* destination, unsigned int truncatedLength); 

/* Writes a string to a textfile. 
    Textfile is supposedly open before and continiues to be opened after */ 
void dstring_print(DString stringToPrint, FILE* textfile); 

/* frees the memory for a dynamic string and set the string(*stringToDelete) to NULL */ 
void dstring_delete(DString* stringToDelete); 

#endif 

.C файл

#include "dstring.h" 
#include <string.h> 
#include <stdlib.h> 
#include <assert.h> 


DString dstring_initialize(const char* str) 
{ 
    assert(str != NULL); // Precondition 

    DString sameStr; 

    sameStr = (char*) malloc(sizeof(char) * (strlen(str)+1)); // Allokerar en dynamisk sträng 



    sameStr = strcpy(sameStr, str); // Kopierar innehållet i "str" till "sameStr" 

    assert(*sameStr == *str); // Kollar om strängarna har samma innehåll 

    return sameStr; 
} 

int dstring_concatenate(DString* destination, DString source) 
{ 
    assert(*destination != NULL); // Avreferar och man kommer åt innehållet 
    assert(destination != NULL); // Kollar så den inte är tom 
    assert(source != NULL); // kollar så att den innehåller en sträng 

    DString oneSent; 

    oneSent = (char*) realloc(*destination, sizeof(char)*(strlen(*destination)+1) + (strlen(source)+1)); // Omallokerar för två strängar 

    oneSent = strcat(*destination, source); // Sätter ihop *destination och source 

    assert(oneSent == *destination && source); // Kollar om oneSent har samma innehåll som *destination och source 

    return 1; 
} 

void dstring_truncate(DString* destination, unsigned int truncatedLength) 
{ 
    assert(destination != NULL); 
    assert(*destination != NULL); 

    *destination = (char*) realloc(*destination, sizeof(char) * (strlen(truncatedLength) + 1)); // Omallokerar för en sträng 
    *destination = "Department"; 

    assert(strlen(*destination) == truncatedLength); //kollar om längden är 10 
} 

void dstring_print(DString str, FILE* textfile) 
{ 
    assert(textfile != NULL); 

    fprintf(textfile, "%s", str); // textfile är en stdout som printar ut str 

} 

void dstring_delete(DString* stringToDelete) 
{ 
    assert(stringToDelete != NULL); // Kollar om det finns något att frigöra 

    *stringToDelete = NULL; // Tömmer innehållet i strängen 

    free(*stringToDelete); // Frigör minnet 

    assert(*stringToDelete == NULL); 
} 

Test FILE

#include <assert.h> 
#include <string.h> 

#include "dstring.h" 


int main(void) 
{ 
    DString str1, str2; 
    str1 = dstring_initialize("Department of "); 
    str2 = dstring_initialize("Redundancy "); 
    dstring_concatenate(&str1, str2); 



    assert(str1 != NULL); 
    assert(str2 != NULL); 
    assert(strlen(str2) == 11); 
    assert(strlen(str1) == 25); 



    dstring_print(str1, stdout);  
    dstring_truncate(&str1, 10);  
    dstring_print(str1, stdout);  


    dstring_delete(&str1); 
    dstring_delete(&str2); 


    assert(str1 == NULL); 
    assert(str2 == NULL); 
    return 0; 
} 
+0

вне темы, но 'dstring_truncate' является функцией, а не классом –

+4

Разница между' malloc' и 'realloc', как представляется, достаточно четко описана на странице руководства. – larsks

+1

Вам нужно направить хорошую книгу C, ИМХО. –

ответ

0
*destination = (char*) realloc(*destination, sizeof(char) * (strlen(truncatedLength) + 1)); // Omallokerar för en sträng 

Прежде всего, не отбрасывают результат таНос или перераспределить.

*destination = realloc(*destination, sizeof(char) * (strlen(truncatedLength) + 1)); // Omallokerar för en sträng 

Кроме того, sizeof(char) всегда 1, так это излишним.

Ваша проблема заключается в том, что вы звоните strlen(truncatedLength), но это int. Вы, вероятно, имел в виду, чтобы позвонить

*destination = realloc(*destination, sizeof(char) * (truncatedLength + 1)); // Omallokerar för en sträng 

Однако вы сразу же перезаписью с

*destination = "Department"; 

так realloc не служит никакой цели.

Если вы хотите переписать содержимое, вам необходимо использовать strcpy или аналогичную функцию.

Однако я предполагаю, что вы не собираетесь заменять содержимое при усечении. В этом случае вам нужно добавить терминатор в строку:

(*destination)[truncatedLength] = '\0'; 

в результате:

void dstring_truncate(DString* destination, unsigned int truncatedLength) 
{ 
    assert(destination != NULL); 
    assert(*destination != NULL); 

    *destination = realloc(*destination, truncatedLength + 1); // Omallokerar för en sträng 
    (*destination)[truncatedLength] = '\0'; 

    assert(strlen(*destination) == truncatedLength); //kollar om längden är 10 
} 

Разница между malloc и realloc что realloc принимает указатель и размер, в то время как malloc только принимает размер. realloc возвращает указатель на ячейку памяти, содержащую те же данные, что и исходный указатель (при необходимости копирование данных и освобождение предыдущего указателя), но с указанным размером.

Смежные вопросы