1

I am learning the basics of memory allocation in C(C++).

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
void main(){

    char *str;
    char *input;
    int *ilist;
    int i, size1, size2;

    printf("Number of letters in word: ");
    scanf("%d", &size1);
    printf("Number of integers: ");
    scanf("%d", &size2);                  

    str = (char *)malloc(size1*sizeof(char) + 1); 

    ilist = (int *)malloc(size2*sizeof(int)); 
    if (str == NULL || ilist == NULL){ 
        printf("Lack of memory");
    }
    printf("Word: ");
    int k = size1;
    // the following line is done to prevent memory bugs when the amount of 
    letters in greater than size1.
    scanf("%ks", &str); //I guess something is wrong with this line
    /* user inputs a string */
    for (i = 0; i < size2; i++) {
        printf("Number %d of %d: ", i + 1, size2);
        //this scanf is skipped during the execution of the program
        scanf("%d", ilist + i);         
    }


    free(str);
    free(ilist);
    system("pause");

}

The program asks user to write the amount of letters in the word and the amount of digits in the number. Then user writes the word. Then he writes integer one-by-one depending on what number was typed before. The problem I have is when the user writes the whole word, next scanf is skipped. Thank you. P.S. can there be other kind of memory bugs in this code?

2 Answers2

2

Regarding //I guess something is wrong with this line...
The format specifier "%ks" in scanf("%ks", &str); contains a k, which is not a valid scanf() format specifier.

Excerpt from link:
enter image description here

For user input value in the width specifier, you can create a format buffer:

char format[10];
int k = size1;//assume size1 == 10
sprintf(format, "%c%d%c", '%', k, 's');
//assuming k == 10, format contains "%10s"
scanf(format, &str); //now, there is nothing wrong with this line

Other Observations
There are several recommended prototypes for the C main function. void main() is not one of them.

This line: str = (char *)malloc(size1*sizeof(char) + 1);
Could be written as:

str = malloc(size1 + 1); //removed sizeof(char) as it is always 1
                         //removed cast, not recommended in C

Similar for for: ilist = (int *)malloc(size2*sizeof(int));

ilist = malloc(size2*sizeof(int));//remove cast, but keep sizeof(int) 
                                  //unlike sizeof(char), sizeof(int) is never 1 

A few Basics to consider for dynamic memory allocation in C:

1) In C, do not cast the output of calloc(), malloc() or realloc(). (do however cast in C++.)
2) For each call to calloc(), malloc() or realloc(), there must be a corresponding call to free()
3) While automatic memory is sourced from the stack, dynamic memory comes from the heap
4) If speed efficiency is important, favor the stack over the heap.

Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87
1

Instead of using scanf use fgets. But, you need to clear the input buffer first to consume the \n left behind by previous scanfs.

int c;
while((c = getchar()) != '\n' && c != EOF); // Clear input buffer  
fgets(str, k, stdin);  

Note that if a '\n' is read then it will be stored in str. You should have to take care of that.

haccks
  • 104,019
  • 25
  • 176
  • 264