Как передать указатель на функцию?

Как передать p[0] функции и распечатать ее содержимое?

#include "stdio.h"
    
void setupMidiOctave(int *p[]) {
    int a[] = {1, 2, 3};
    int b[] = {4, 5, 6};

    p[0]    = &a[0];
    p[1]    = &b[0];
}

void prt(int *a) {
    printf("%d\n", a[1]);
}

int main(void) {
    int *p[2];
    setupMidiOctave(p);
    printf("%d\n", p[0][0]);
    prt(p[0]); // <--------- not printing out
    return 0;
}

Вы не можете использовать указатели на локальные переменные после возврата функции. &a[0] становится недействительным после возврата setupMidiOctave().

Barmar 23.04.2024 01:45

Либо создайте a и b статические или глобальные переменные, либо выделяйте память динамически.

Barmar 23.04.2024 01:48

Почему p представляет собой массив указателей, а не просто массив целых чисел?

Barmar 23.04.2024 01:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Внутри setupMidiOctave вы пытаетесь вернуть указатели в два массива, объявленные с автоматическим сроком хранения. После завершения вызова функции эти указатели больше не указывают на действительную память. Попытка их использования вызывает неопределенное поведение.

Чтобы преодолеть это в вашей ситуации, a и b необходимо выделять динамически, чтобы они переживали вызов функции.

void setupMidiOctave(int *p[]) {
    int *a = malloc(sizeof(*a) * 3);
    int *b = malloc(sizeof(*b) * 3);

    a[0] = 1; a[1] = 2; a[2] = 3;
    b[0] = 4; b[1] = 5; b[2] = 6;

    p[0] = a;
    p[1] = b;
}

Но теперь не забудьте free выделить эту динамически выделяемую память, когда закончите с ней.

Вам также следует завести привычку проверять, что malloc удалось. Возможно, вы захотите, чтобы ваша функция возвращала значение, указывающее на это. Вы захотите выполнить очистку, если первый malloc удался, а второй не удался, чтобы избежать утечек памяти. Это также делает использование a и b более разумным, поскольку теперь у нас есть возможность не перезаписывать p, если динамическое выделение не удалось.

int setupMidiOctave(int *p[]) {
    int *a = malloc(sizeof(*a) * 3);
    if (!a) {
        return 0;
    }

    int *b = malloc(sizeof(*b) * 3);
    if (!b) {
        free(a);
        return 0;
    }

    a[0] = 1; a[1] = 2; a[2] = 3;
    b[0] = 4; b[1] = 5; b[2] = 6;

    p[0] = a;
    p[1] = b;

    return 1;
}

На этот раз я не голосую против ответа, но, пожалуйста, не отвечайте на очевидные дубликаты, которые уже задавались миллион раз. Вместо этого закройте как дубликат. Список целей можно найти в вики-странице тега C ниже раздела «Часто задаваемые вопросы».

Lundin 23.04.2024 08:18

Другие вопросы по теме