-1

I created a couple of functions in my program. In my class "void dstring_truncate(DString* destination, unsigned int truncatedLength);" I allocate memory the wrong way. How should I allocate memory the right way? Also got a question about realloc and malloc. What is the diffrence between them?

Header file

#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 file

#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;
}
alifarlig
  • 23
  • 4

1 Answers1

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

First of all, do not cast the result of malloc or realloc.

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

Also, sizeof(char) is always 1, so it's redundant.

Your issue here is that you're calling strlen(truncatedLength), but that is an int. You probably meant to call

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

However you're immediately overwriting it with

*destination = "Department";

so the realloc serves no purpose.

If you want to overwrite the contents, you need to use strcpy or a similar function.

However, I assume you don't mean to replace the content when truncating. In that case, you need to add a terminator to the string:

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

resulting in:

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
}

The difference between malloc and realloc is that realloc takes a pointer and a size, while malloc only takes a size. realloc returns a pointer to a memory location containing the same data as the original pointer had (copying the data and freeing the previous pointer if necessary), but with the size specified.

Tordek
  • 10,628
  • 3
  • 36
  • 67