Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 08.05.2011
Сообщений: 9
1

Аргументы-указатели и динамическая матрица, проблема с реализацией функции

28.10.2011, 21:40. Показов 1272. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, форумчане!
У меня следующая проблема: в main определена переменная-указатель на указатель(к примеру char **ptr; ), необходимо написать функцию, которая бы создала матрицу при помощи ф-й выделения дин.памяти, присвоила элементам некоторые значения, и чтобы этот ptr в итоге указывал бы на эту матрицу. Т.е. суть в том, чтобы выделение памяти было вне main(), но в тоже время, чтобы можно было из main() освободить память, выделенную под ту матрицу без использования статических,глобальных и т.п. переменных.
Вот мой очень грубый пример, чисто для иллюстрации идеи.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
void matr( int size, char ***ptr, char *data )
     {
      *ptr = (char **) calloc( size, sizeof(char *) );
      for( int i=0; i<size; i++ )
           {
         *ptr[i] = (char *) calloc( size, sizeof(char) );
         strcpy( *ptr[i], data); 
           }
          printf("%s",*ptr[1]);              
     }
...
int main( )
         {
           ...
           char **PTR = NULL;
 
           matr( 2, &PTR, "13" );
           printf("\n%s",ptr[1]);
           ...
         }
В результате в консоли имеем
C
1
2
13
(null)
Когда строится матрица 3x3 и больше то программа крашится при обращениях из main(), память внезапно оказывается не выделенной, кроме первых двух эл-тов.
Почему так произошло и как этого избежать?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.10.2011, 21:40
Ответы с готовыми решениями:

Динамическая матрица, не выводит через указатели
Если матрица квадратная, все норм, если прямоугольная пишет ошибку и вылетает. Просто не пойму...

Проблема с реализацией функции поиска по структуре
Столкнулся со следующей проблемой: Есть структура. struct Bicycle { int index; char model;...

Создание функции, формирующую предложение из аргументов функции, аргументы . Аргументы - переменное число
Короче, вот бы всё норм. Хочу соединять, но он мне выдаёт ошибку, когда использую strcat. Не могу...

Транслируются ли аргументы функции CoCreateInstance в аргументы функции DllGetClassObject?
НУ то есть я думаю должно быть понятно, о чём речь. В клиенте вызывается функция: ...

7
Заблокирован
28.10.2011, 21:46 2
У вас уже здесь ошиька
Код
*ptr = (char **) calloc( size, sizeof(char *) );
Тип *ptr является char *, а вы присваиваете ему указатель типа char **

По крайней мере следует писать

Код
ptr = (char **) calloc( size, sizeof(char *) );
0
0 / 0 / 0
Регистрация: 08.05.2011
Сообщений: 9
29.10.2011, 15:12  [ТС] 3
Цитата Сообщение от Сыроежка Посмотреть сообщение
У вас уже здесь ошиька
В данном коде нет ошибок синтаксиса, если Вы об этом.
А переменная ptr заявлена в matr как char ***, а разыменованием я "понижаю" ее до char **, где же здесь ошибка?

Добавлено через 17 часов 21 минуту
Ошибка найдена - в строке 7(8,10) имеется *ptr[i], на самом деле имелось в виду (*ptr)[i]. Исправление приводит к корректной работе.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
29.10.2011, 15:28 4
надо делать это же, но по-другому
в функции создай локальный указатель на указатель
помести в него матрицу, заполни её
а потом в конце *ptr = p;
(вообще, матрицу делаешь одной функцией, а заполняешь другой функцией)
1
Заблокирован
29.10.2011, 15:30 5
Цитата Сообщение от Someone_ Посмотреть сообщение
У меня следующая проблема: в main определена переменная-указатель на указатель(к примеру char **ptr; ), необходимо написать функцию, которая бы создала матрицу при помощи ф-й выделения дин.памяти, присвоила элементам некоторые значения, и чтобы этот ptr в итоге указывал бы на эту матрицу. Т.е. суть в том, чтобы выделение памяти было вне main(), но в тоже время, чтобы можно было из main() освободить память, выделенную под ту матрицу без использования статических,глобальных и т.п. переменных.
нужна поддержка С99, или вынесете объявление типов из циклов for()
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
char **create_matrix(const size_t N, const size_t M)
{
    char **tmp = 0;
 
    tmp = (char**) malloc (N * sizeof(char*));
    if (!tmp)
        exit ( -1 );
 
    for (int i = 0; i < N; ++i){
        tmp[i] = (char*) malloc(M * sizeof(char));
        if (!tmp[i])
            exit ( -1 );
    }
 
    for (int i = 0; i < N; ++i)
        for (int k = 0; k < M; ++k)
            tmp[i][k] = rand() % 2;
 
    return tmp;
}
 
void print_matrix(char **matr, const size_t N, const size_t M)
{
    for (int i = 0; i < N; ++i){
        printf("\n");
        for (int j = 0; j < M; ++j)
            printf("%d ", matr[i][j]);
    }
}
 
int main ()
{
    char **matr;
    const size_t N = 8;
    const size_t M = 16;
    srand(time(0));
 
    matr = create_matrix(N, M);
    print_matrix(matr, N, M);
 
    for (int i = 0; i < N; ++i)
        free(matr[i]);
    free(matr);
    return 0;
}
консоль
0 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0
1 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0
0 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0
1 1 1 0 1 0 0 0 0 0 1 0 1 1 0 1
1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0
1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1
0 1 0 0 1 1 1 0 1 1 1 0 0 1 1 1
0 1 0 1 0 0 0 0 1 0 0 1 1 0 1 1
1
Заблокирован
29.10.2011, 18:19 6
Цитата Сообщение от Someone_ Посмотреть сообщение
В данном коде нет ошибок синтаксиса, если Вы об этом.
А переменная ptr заявлена в matr как char ***, а разыменованием я "понижаю" ее до char **, где же здесь ошибка?

Добавлено через 17 часов 21 минуту
Ошибка найдена - в строке 7(8,10) имеется *ptr[i], на самом деле имелось в виду (*ptr)[i]. Исправление приводит к корректной работе.
Вы уж там три звездочки поставили в параметр?! Я даже не заметил. Но это очень плохой стиль программирования! Можно запутаться в звездочках.

Вам следовало бы переопределить функцию таким образом, чтобы вместо void она возвращала указатель на выделенную память. То есть у вас крайне плохой интерфейс функции.
0
0 / 0 / 0
Регистрация: 08.05.2011
Сообщений: 9
29.10.2011, 22:25  [ТС] 7
Цитата Сообщение от Сыроежка Посмотреть сообщение
... То есть у вас крайне плохой интерфейс функции.
Естественно. Я писал в первом посте, что это грубый пример, иллюстрирующий идею. Реальная функция имеет тип int и возвращает размерность матрицы в случае успеха или код ошибки, в случае неудачи. Т.к. два параметра возвратить нельзя, значение указателя на выделенную память передается за счет переданного функции адреса локальной переменной из main(). А насчет того, что можно запутаться согласен.
accept и alkagolik, я обязательно попробую, то что вы предложили, спасибо.
На этом можно считать тему исчерпанной
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
30.10.2011, 08:28 8
Цитата Сообщение от Someone_
Реальная функция имеет тип int и возвращает размерность матрицы в случае успеха или код ошибки, в случае неудачи.
C
1
int create_matrix(char ***p, int rows, int cols);
где единица - в случае успеха и ноль - в случае ошибки
или где ноль - в случае успеха и не ноль - в случае ошибки
0
30.10.2011, 08:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.10.2011, 08:28
Помогаю со студенческими работами здесь

Нужна помощь с реализацией программы, использующей списки и указатели
Ситуация такая. Работаю в Lasarus. Нужна помощь с реализацией программы. Задание: Разработать...

Проблема с реализацией
Доброе! такая вот реализация: открываю документ (Maindoc) создаю из него респонс, при сохранении...

Указатели на функции. Указатели на функции как формальные параметры у функциях высшего уровня
Найти наименьшее значение для функций используя функции и указатели на функции ...

Проблема с реализацией программы
как в кнопку (Button1 например) вставить код: template&lt;class T&gt; void quickSortR(T* a, long N) {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru