Home > Net >  I can't free the memory
I can't free the memory

Time:12-21

I'm in my 1st year of faculty and I have this homework:

Write a program that reads n arrays of characters and concatenates them into another dynamically allocated array. Repeat the operation as many times as the user desires.

After each displaying of the result, the allocated memory is freed.

And that is what I did:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>

int main()
{
    char** p, * v;
    int n, m;
    printf("\n\t enter the number of the arrays : \t");
    scanf("%d", &n);
    printf("\n\t enter the maximum lenght of the arrays :");
    scanf("%d", &m);
    p = (char**)malloc(sizeof(char) * n);

    for (int i{}; i < n; i  )
        p[i] = (char*)malloc(sizeof(char) * m);

    char t = 'Y';
    while (t == 'Y')
    {
        size_t z = 0;
        printf("\n\t enter your arrays :");
        for (int i{}; i < n; i  ) {
            scanf("%s", p[i]);
            z  = strlen(p[i]);
        }
        v=(char* )malloc(z * sizeof(char));
        for (int i{}; i < n; i  )
            if (i == 0)
                strcpy(v, p[i]);
            else
                strcat(v, p[i]);
        if (v) {
            puts(v);
            free(v);
        }

        if (p)
            for (int i{}; i < n; i  )
                free(p[i]);

        printf("\n\t wanna continue ? (Y/N)");
        scanf("%d", &t);
    }
}

When I want to free the memory to use again, I get a "head corruption error" from the debugger.

Any idea why?

CodePudding user response:

Allocation size mistake

Code allocated the wrong size. p is a pointer, not a char. Cast not needed either.

char** p; 
...
p = (char**)malloc(sizeof(char) * n);  // Bad

Size to the tpye of the referenced object. It is easier to code right, review and maintain than attempting to code the matching type.

p = malloc(sizeof *p * n);  // Good
...
  p[i] = malloc(sizeof *p[i] * m);

Robust code would also check for errors.

if (scanf("%d", &n) != 1 || n < 0) {
  fprintf(stderr, "No numeric input or negative count\n");
  // Perhaps exit here.
}

p = malloc(sizeof *p * n);
if (p == NULL && n > 0) {
  fprintf(stderr, "Allocation failed\n);
  // Perhaps exit here.
}

Other enter image description here

CodePudding user response:

I get warnings, maybe I forgot some checks (malloc/scanf).

I hope I helped you even though I’m a beginner.

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdbool.h>

struct cstring {

    char* data;
    size_t size;

};

bool create_cstring(struct cstring* const object, const size_t size) {

    return (object->data = calloc(size, sizeof(char))) ?
        (object->size = size   1U) :
        (object->size = 0U);

}

bool destroy_cstring(struct cstring* const object) {

    free(object->data);
    object->size = 0U;

}

struct cvector_string {

    struct cstring* data;
    size_t size;

};

bool create_cvector_string(struct cvector_string* const object, const size_t size) {

    return (object->data = calloc(size, sizeof(struct cstring))) ?
        (object->size = size) :
        (object->size =   0U) ;

}

void destroy_cvector_string(struct cvector_string* const object) {

    free(object->data);
    object->size = 0U;

}

int main()
{

    struct cvector_string cv = { NULL, 0U };

    // Allocations 
    {

        // Allocate n arrays of chars
        {

            size_t cv_n = 0;

            printf("\n\t Enter the number of the arrays : \t"); 
            scanf("%zu", &cv_n);

            if (!create_cvector_string(&cv, cv_n)) {

                fprintf(stderr, "Error : Bad allocation\n");
                return 1;

            }

        }

        // Allocate arrays of n chars
        {

            size_t cv_m = 0;

            printf("\n\t Enter the maximum lenght of the arrays : \t");
            scanf("%zu", &cv_m);

            for (struct cstring* it = cv.data; it != cv.data   cv.size;   it) {

                if (!create_cstring(it, cv_m)) {

                    fprintf(stderr, "Error : Bad allocation\n");
                    return 1;

                }

            }

        }

    }

    struct cstring r = { NULL, 0U };


    {

        char cont = '\0';

        do {

            /* Initialize arrays of chars, calculate the length of the resulting string
             * and create the resulting string */
            {

                size_t length_sum = 0;

                for (struct cstring* it = cv.data; it != cv.data   cv.size;   it) {

                    scanf("%s", it->data);
                    length_sum  = strlen(it->data);

                }

                if (!create_cstring(&r, length_sum)) {

                    fprintf(stderr, "Error : Bad allocation\n");
                    return 1;

                }

            }

            // Initialize and concatenate the resulting string
            {

                strcpy(r.data, cv.data[0].data); 
                // or using destination = strcpy(malloc, source), same for strcat

                for (struct cstring* it = cv.data   1; it != cv.data   cv.size;   it) strcat(r.data, it->data);

            }


            // Print and deallocate the resulting string

            puts(r.data);
            destroy_cstring(&r);

            // Prompt to continue

            printf("\n\t Wanna continue? (Y/N) ");
            scanf(" %c", &cont);

        } while (cont == 'Y');

    }

    // Deallocations 
    {

        // Deallocate all the arrays of chars
        for (struct cstring* it = cv.data; it != cv.data   cv.size;   it) destroy_cstring(it);

        // Deallocate the array of arrays of chars
        destroy_cvector_string(&cv);

    }

}

Errors :

  1. You’re freeing the allocated memory for character arrays and then reading into that memory.

Deallocating

 for (int i{}; i < n; i  )
                free(p[i]);

Using

 for (int i{}; i < n; i  ) {
            scanf("%s", p[i]);
            z  = strlen(p[i]);
        }
  1. You have to allocate memory for pointers, not allocate memory for characters.

    p = (char**)malloc(sizeof(char) * n);
    
  •  Tags:  
  • c
  • Related