2015-12-05 2 views
0

Я хочу написать небольшую программу на языке C, которая запрашивает у пользователя номер ввода length_input, а затем печатает первые символы length_input некоторой фиксированной строки string_input.Как вернуть массив неизвестного размера в C

Теперь этот код не работает. Он компилируется отлично, но он всегда печатает пустую строку вместо "AB", например.

#include <stdio.h> 
#include <stdlib.h> 

char* take (char* string, int length) { 

    char* local_string = malloc(length); 

    for (int i = 0; i < length; i++) { 
     local_string[i] = string[i]; 
    } 

    return local_string; 
} 

int main (int arg, char** args) { 

    char* string_input; 
    char* string_output; 
    int length_input; 

    printf("> "); 
    scanf("%s", &length_input); 

    string_input = "ABCDEFG"; 
    string_output = malloc(length_input); 
    string_output = take(string_input, length_input); 

    printf(string_output); 
    printf("\n"); 
    return 0; 
} 

Я предполагаю, что это потому, что я возвращаю локальную переменную в take, нет? Я также прочитал, что объявление указателя local_string в качестве статической переменной поможет. Я понимаю, что его распределенный размер затем должен быть известен во время компиляции, что сделает программу бессмысленной.

Дело в том,: Вызов take должно не изменить какие-либо локальные переменные main процедуры, или быть более точным: Это должно изменить ничего, что определяется с помощью main процедуры - будь то в стеке или в куче. Поэтому мне нужно вернуть новый указатель на новый адрес в куче, а не изменять значения в существующем. (Почему? Это эксперимент.)

Можно ли делать то, что я хочу? Если да, то как?

+1

Это 'scanf ("% s ", & length_input);' должен заставить компилятор вас предупредить. Будьте осторожны. – alk

+0

@alk Но я не получил предупреждения? Я скомпилировал с помощью 'gcc -o output program.c', используя' gcc (Debian 5.2.1-23) 5.2.1 20151028'. Нет предупреждений. –

+0

Ваша функция 'take' не завершает нуль строки. выделите 'length + 1' bytes и сделайте' local_string [length] = '\ 0'' –

ответ

3

Сначала рассмотрим, что это делает scanf

scanf("%s", &length_input); 

Он принимает входной текст и преобразует его в строку (% S) (что это уже есть), а затем сохраняет его в & length_input (адрес целого). Наверное, не то, что ты хочешь.

Примечание: length_input, вероятно, все еще будет '0' (его начальное значение)

Затем он не выделяет никакой памяти (таНос (0)); но, поскольку большинство mallocs имеют минимальный размер, вы получили что-то.

Затем он вызывает «принять», который запускает цикл один раз, чтобы получить первую запись в массиве («AB») и сохраняет это в удачном буфере.

Тогда вы не освободили то, что вы malloced; поэтому вы, вероятно, просочились в память.

У вас есть несколько причин исправить; но, он сделал то, что вы ему сказали.

+0

Да! В предыдущей версии программы запрашивалась строка, и я не менял '% s' на'% i'. Теперь я изменил его, и теперь он работает. –

1

Ваша функция take в порядке. Однако они, как вы его вызываете, не в порядке. Вы должны делать:

string_input = "ABCDEFG"; 
string_output = take(string_input, length_input); 

В противном случае вы получите утечку памяти.

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