2016-05-15 21 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); 
} 

テストファイル

#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'の違いは、manページにはっきりと記述されているようです。 – larsks

+1

良いC本IMHOを参照する必要があります。 –

答えて

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

まず、malloc関数またはreallocの結果をキャストしないでください。

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

また、sizeof(char)は常に1あるので、それは冗長です。

あなたの問題は、あなたがstrlen(truncatedLength)に電話していますが、それはintです。あなたは、おそらくそうreallocは目的を達成しませんあなたはすぐに

*destination = "Department"; 

でそれを上書きしているが

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

を呼び出すためのもの。

コンテンツを上書きする場合は、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 
} 

mallocreallocの違いはreallocmallocながら、ポインタとサイズを取ることであるのみサイズがかかります。 reallocは、元のポインタと同じデータを含むメモリ位置へのポインタを返します(データをコピーし、必要に応じて前のポインタを解放します)が、サイズは指定されています。