2016-01-02 5 views
1

Я изучаю основы выделения памяти в 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"); 

} 

Программа просит пользователя написать количество букв в слове и количество цифр в номере. Затем пользователь записывает слово. Затем он пишет целое число один за другим в зависимости от того, какое число было напечатано ранее. Проблема заключается в том, когда пользователь записывает все слово, следующий scanf пропускается. Спасибо. P.S. могут ли быть другие типы ошибок памяти в этом коде?

+3

Рекомендуется проверить возвращаемое значение 'scanf'. – ilent2

+2

Первый урок c! = C++, а в c вы не накладываете 'malloc()' на тип указателя цели, потому что вам это не нужно. –

+1

Я предлагаю установить Valgrind http://valgrind.org/ для проверки утечек памяти. – birdoftheday

ответ

1

Вместо использования scanffgets. Но вам нужно сначала очистить входной буфер, чтобы потреблять \n, оставшийся позади предыдущего scanf s.

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

Обратите внимание, что если '\n' читается, то он будет храниться в str. Вы должны позаботиться об этом.

+0

Или используйте 'getline' –

+0

@BasileStarynkevitch; Не стандартная функция библиотеки C. – haccks

+1

@haccks: Но это POSIX. – alk

2

Что касается // Я предполагаю, что-то не так с этой линией ...
спецификатор формата "%ks" в scanf("%ks", &str); содержит к, которое не является действительным scanf() format specifier.

Отрывок из ссылки:
enter image description here

Для пользователя входного значения в width спецификаторе, вы можете создать формат буфер:

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 

Других замечания
Есть several recommended prototypes for the C main function. void main() не является одним из них.

Эта линия: str = (char *)malloc(size1*sizeof(char) + 1);
Может быть записано как:

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

Похожие на для: 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 

Несколько Основы рассмотреть для динамического распределения памяти в C:

1) В C, не отбрасывают выход из calloc(), malloc() or realloc(). (однако, накладывать на C++.)
2) Для каждого вызова calloc(), таНос() или перераспределить(), должен быть соответствующий вызов free()
3) В то время как автоматическая память соерсед из stack, динамической памяти происходит от heap
4) Если speed efficiency is important, благоприятствуют стек по куче.

Смежные вопросы