Home > other >  malloc() in C returns populated memory
malloc() in C returns populated memory

Time:03-01

char *string = (char *) malloc(sizeof(char) * sz);

code right before this->void insert_word(word *root, char string1[], int linenumber) { int sz=strlen(string1)<=MAX_WORD_LENGTH?strlen(string1):MAX_WORD_LENGTH; Code block 3 has the entire context

Sometimes malloc() returns a populated memory location while using it.

What bothers me is that this is not random. (This program consists of taking words from a file and passing them to this function. For THE SAME WORD, the function behaviour(in particular that of malloc()) is different.

For the inputs string1=0x7fffffffdf10 "lol" root=BST, sz gets a value of 3

The value allocated to string by malloc() is 0x55555555c510 "\340\305UUUU" Why is malloc not pointing to an empty memory location? (This is not random behaviour, it is predictable and repeatable) Furthermore,this loop runs an infinite amount of time for some reason

while(strcmp(string1,string)!=0)
    {
        free(string);
        string=NULL;
        string = (char *) malloc(sizeof(char) * sz);
        strncpy(string,string1,sz);
    }

MORE RELAVANT CODE

  1. #define MAX_WORD_LENGTH 20

  2. Definition of the structures

    typedef struct linkedList
        {
            int number;
            struct linkedList *next;
        }list;
        typedef struct word_with_count
        {
            char* string;
            list *linenumbers;
            struct word_with_count *left;
            struct word_with_count *right;
        }word;```
    

[3] ) The function

void insert_word(word *root, char string1[], int linenumber) {
    int sz=strlen(string1)<=MAX_WORD_LENGTH?strlen(string1):MAX_WORD_LENGTH;
    char *string = (char *) malloc(sizeof(char) * sz);
    strncpy(string,string1,sz);
    if (root==NULL) {
        return;
    } else if (strcmp(string, root->string) < 0) {
        if (root->left == NULL) {
            root->left = createword(string, linenumber);
        } else {
            insert_word(root->left, string, linenumber);
        }
    } else if (strcmp(string, root->string) > 0) {
        if (root->right == NULL) {
            root->right = createword(string, linenumber);
        } else {
            insert_word(root->right, string, linenumber);
        }
    } else {
        append_list(linenumber, root->linenumbers);
    }
    free(string);
}
  1. main() which calls this function
int main() {
    char path[MAX_PATH_LENGTH];
    FILE *fp;
    fgets(path, MAX_PATH_LENGTH, stdin);

    if (strlen(path) > 0 && path[strlen(path) - 1] == '\n')
        path[strlen(path) - 1] = '\0';
    
    fp = fopen(path, "r");
    if (fp == NULL) {
        printf("File not found\n");
        return 0;
    }
    char ch;
    int line_count = 1;
    char current_word[MAX_WORD_LENGTH] = "";

    word *root = NULL;
    while (!feof(fp)) {
        ch = fgetc(fp);
        //printf("%c", ch);

        if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
            if (ch >= 'A' && ch <= 'Z')
                ch = ch - 'A'   'a';

            strncat(current_word, &ch, 1);
        } else if (ch == '-') {
            continue;
        } else {
            if (strlen(current_word) > 2) {
                if (root == NULL) {
                    root = createword(current_word, line_count);
                } else {
                    insert_word(root, current_word, line_count);
                }
            }
            memset(current_word, 0, sizeof(current_word));
            if (ch == '\n') {
                line_count  ;
            }
        }
    }
    if (strlen(current_word) > 2) {
        if (root == NULL) {
            root = createword(current_word, line_count);
        } else {
            insert_word(root, current_word, line_count);
        }
    }
    fclose(fp);
    // print_tree(root);
    //printf("\n");
    //print_tree(root);
    int status=delete_low_ocurrence(root, NULL, 3);
    if (status == -1)root = NULL;
    print_tree(root);
    freetree(root);
    return 0;
}

5)Auxilary function used by this function

word* createword(char string[], int linenumber)
{
    word *newword = (word*)malloc(sizeof(word));
    int sz=strlen(string)<=MAX_WORD_LENGTH?strlen(string):MAX_WORD_LENGTH;
    newword->string = (char*)malloc(sizeof(char)*sz);
    strncpy(newword->string, string,sz);
    newword->linenumbers = (list*)malloc(sizeof(list));
    newword->linenumbers->number = linenumber;
    newword->linenumbers->next = NULL;
    newword->left = NULL;
    newword->right = NULL;
    return newword;
}
  1. Textfile given as input
much2f
much3f
lol
lol
lol
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiop

CodePudding user response:

Why is malloc not pointing to an empty memory location?

Because it can. The content of the allocated memory via malloc() is not specified.

If code needs zeroed out memory, see calloc().


Bad code

strncpy(string,string1,sz) does not result in string being a string as it may lack null character termination. The following (strcmp(string... is then undefined behavior. Instead, do not use strncpy(), use strcpy() and make certain the prior allocation has enough room for the terminating null character.

strncpy(string,string1,sz);
...
} else if (strcmp(string, root->string) < 0) { // bad

Repaired code

word* createword(const char string[], int linenumber) {
  word *newword = calloc(1, sizeof *newword);
  size_t length = strlen(string);
  if (length > MAX_WORD_LENGTH) {
    length = MAX_WORD_LENGTH;
  }
  char *s = malloc(length   1); // Include room for the \0
  list *linenumbers = calloc(1, sizeof *linenumbers);
  // Test allocation success
  if (newword == NULL || s == NULL || linenumbers == NULL) {
    free(newword);
    free(s);
    free(linenumbers);
    return NULL;
  }
  memcpy(s, string, length);  // Only copy the first 'length' characters.
  s[length] = 0;
  newword->string = s;
  newword->linenumbers = linenumbers;
  newword->linenumbers->number = linenumber;
  newword->linenumbers->next = NULL;
  newword->left = NULL;
  newword->right = NULL;
  return newword;
}

Why is “while ( !feof (file) )” always wrong?

feof(fp) improperly used here. fgetc() returns 257 different values. Do not use char ch.

//char ch;
//...
//while (!feof(fp)) {
//    ch = fgetc(fp);

int ch;
...
while ((ch = fgetc(fp)) != EOF) {;

CodePudding user response:

This is quite normal behaviour. 'malloc' just does the memory allocation, it makes no commitment on what's already in that memory location. What you probably need is 'calloc', which clears the memory and then allocates it to your program.

  • Related