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?

15
  • 3
    It's a good idea to check the return value of scanf. Commented Jan 2, 2016 at 16:32
  • 2
    First lesson c != c++ and in c you don't cast malloc() to the target pointer type because you don't need to. Commented Jan 2, 2016 at 16:32
  • 1
    I suggest installing Valgrind valgrind.org to check for memory leaks. Commented Jan 2, 2016 at 16:32
  • 2
    @EdHeal; No. From C99, return type should be int. Commented Jan 2, 2016 at 17:08
  • 2
    @EdHeal: For a hosted env/ it's UB as per the C11 Standard appendix J2 along with 5.1.2.2.1. Commented Jan 2, 2016 at 17:11

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

2 Comments

@BasileStarynkevitch; Not a standard C library function.
@haccks: But it's POSIX.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.