небольшая программа со связанным списком в c, случайный вывод printf - PullRequest
0 голосов
/ 17 марта 2020

Я пишу небольшую школьную программу, я должен использовать 'void const * content' в качестве параметра. У меня проблемы с печатью содержимого нового узла. без 'const' код работает и отображает все правильно. кто-то может указать, что я делаю неправильно?

вывод терминала: � 6


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

    typedef struct s_list
    {
        void        *content;
        size_t      content_size;
        struct      s_list *next;
    }               t_list;

t_list  *lstnew(void const *content, size_t content_size)
{
    struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));
    if(new == NULL){
        printf("No allocation!");
        exit(1);
    }

    new->content = &content;
    new->content_size = content_size;
    new->next = NULL;


    return(new);
}

int     main(void)
{

    printf("%s\n", lstnew("Hello", 6)->content);
    printf("%zu\n", lstnew("Hello", 6)->content_size);

    return(0);
}

Ответы [ 2 ]

4 голосов
/ 17 марта 2020

Здесь вы берете адрес локальной переменной:

new->content = &content;

Вместо этого просто примите значение:

new->content = content;

Кроме того, вы не выделяете здесь достаточно памяти ; Вы только выделяете достаточно для указателя вместо размера структуры:

struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));

Приведение на malloc также не требуется. Я бы написал так:

struct s_list *new = malloc(sizeof(*new));

Вместо использования typedef и t_list, вы должны просто использовать struct s_list везде, потому что структура не должна быть непрозрачной.

0 голосов
/ 17 марта 2020

В этом объявлении

struct s_list *new = (struct s_list*)malloc(sizeof(struct s_list*));

вместо памяти выделения для объекта типа struct s_list выделяется память для указателя типа struct s_list *.

. написать

struct s_list *new = malloc( sizeof( struct s_list ) );

или

t_list *new = malloc( sizeof( t_list ) );

В этом выражении

new->content = &content;

левый операнд имеет тип void *, тогда как правый операнд имеет тип const void **. Кроме того, вы используете указатель на локальную переменную content (параметры функции являются ее локальными переменными), которая не будет работать после выхода из функции.

Вам нужно выделить память и скопировать содержимое содержимое переменной в выделенной памяти.

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

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

typedef struct s_list
{
    void *content;
    size_t content_size;
    struct s_list *next;
} t_list;

t_list * lstnew( const void *content, size_t content_size )
{
    t_list *new = malloc( sizeof( t_list ) );

    if ( new != NULL )
    {
        new->content = malloc( content_size );

        if ( new->content == NULL )
        {
            free( new );
            new = NULL;
        }
        else
        {
            memcpy( new->content, content, content_size );
            new->content_size = content_size;
            new->next = NULL;
        }
    }

    return new;
}


int main(void) 
{
    t_list *head = lstnew( "Hello", 6 );
    head->next = lstnew("World!", 7 );

    printf( "%s %s\n", ( char * )head->content, ( char * )head->next->content );

    return 0;
}

Вывод программы:

Hello World!
...