Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с malloc() и указателями в СИ 
:(
    Опции темы
murtukov
Дата 30.1.2013, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 30.1.2013

Репутация: нет
Всего: нет



Всем привет.

Написал программу, которая выделяет память под двумерный массив и сохраняет в него имена. Размер выделяемой памяти зависит от количества и длины слов, которое определяется пользователем. Программка рассчитана на сохранение n-го количества слов, которое также определяется пользователем в начале программы (при запуске).

Вот, собственно, и сам код программы:

Код

#include <stdio.h>
#include <string.h>
 
// функция выделения памяти для одного слова. На входе m - количество букв, определенное с помощью strlen(). *mass - указатель на указатель
void memory_for_string(char *mass, int m)
{
    *mass = (char *)malloc((m+1)*sizeof(char)); // прибавляем к переменной 'm' 1 для выделения места под знак конца строки
}
 
int main(void)
{
    int m=0, n=0, i=0;
    char **mass, str[20];   // **mass - указатель на указатель. str - временный массив для определения длины введенного слова
 
    puts("Please, enter a number of strings");  // пожалуйста, введите число строк
    scanf("%d", &n);
    fflush(stdin);  // очищаем стандартный поток после scanf()
 
    mass = (char *)malloc(n*sizeof(char *));  // выделяется память под массив указателей, адрес первой ячейки сохраняется в mass
 
    while(i<n)  // выполнять, пока не введено n-е количество имен
    {
        printf("Please, enter the name %d: ", i+1);  // пожалуйста, введите i-е имя
        gets(str);  // сохраняем введенное слово
        m = strlen(str);  // определяем длину слова и сохраняем в m
        memory_for_string(mass+i, m);  // запускаем функцию для выделения памяти под длину слова
        strcpy(*(mass+i), str);  // копируем слово в выделенную память
        i++;
    }
 
    i=0;
    while(i<n)
        {
          printf("\nThe name %d is: %s", i+1, *(mass+i));
          i++;
        }
    return 0;
}


Все подробно прокомментировал. Программка выполняется только если вводить два имению Если больше - зависает. Видимо у меня где-то ошибка в понимании указателей или функции malloc(). Прошу помочь найти ошибку в коде.

Спасибо.
PM MAIL   Вверх
feodorv
Дата 30.1.2013, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Код как следует не смотрел, но сразу бросилось в глаза:
Цитата(murtukov @  30.1.2013,  08:32 Найти цитируемый пост)
void memory_for_string(char *mass, int m)
{
    *mass = (char *)malloc((m+1)*sizeof(char)); // прибавляем к переменной 'm' 1 для выделения места под знак конца строки
}

Здесь mass - указатель на char, а не char*, в результате *mass присваивает один char... Правильно:
Код

void memory_for_string(char **mass, int m)...


Добавлено через 4 минуты и 21 секунду
Вообще в таких ситуациях лучше возвращать указатель на заказанную память:
Код

char *memory_for_string( int m ) ...

А ещё лучше сразу же в подпрограмме определять длину копируемой строки, а потом её ещё и скопировать в заказанную память. Получится strdup smile

Добавлено через 11 минут и 2 секунды
Ещё замечание по стилю программирования. Если mass - это массив строк, то лучше к такому массиву обращаться как
Код

memory_for_string(&mass[i], m);





--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
fish9370
Дата 31.1.2013, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



feodorv все грамотно расписал, я лишь добавлю:

- функция malloc может не выделить память (смотри man malloc), при этом следует корректно обработать данную ситуацию. Обычно пишут обертку типа:

Код

inline void * x_malloc(size_t len)
{
        void *p;

        if (!(p = malloc(len)))
                MALLOC_FAILURE_MSG; /* сообщение об ошибке */

        return p;
}


- функция malloc не инициализирует память нулями, если нужно чтобы память была очищена используй calloc (это может быть более быстро, чем очищать самому, так как ядро постарается предоставить буфер уже чистый)

- функцию malloc в Си не обязательно (и не желательно) приводить к типу (смотри пример выше)

Это сообщение отредактировал(а) fish9370 - 31.1.2013, 13:19


--------------------
undefined
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0426 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.