AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-5294916

Oh Fiveight's questions

Martin Hope
Oh Fiveight
Asked: 2025-04-16 08:22:42 +0800 CST

Usando biblioteca compartilhada no GNU/Linux com gcc

  • 5

Questão principal

Estou usando GNU/Linux, enviando código C para uma biblioteca compartilhada bin/libcore.soe, em seguida, usando a biblioteca na criação de um executável bin/test. Os arquivos são criados com sucesso, mas bin/testocorre o seguinte erro ao executar:

bin/test: error while loading shared libraries: libcore.so: cannot open shared object file: No such file or directory

Subquestão

Separei isso em uma questão própria porque pode estar completamente fora do caminho certo.

Li que meu problema pode ser porque preciso definir -Wl,-rpath,binao compilar bin/test(tive que passar por algo parecido para fazer isso funcionar no Windows, ou seja, definir -Wl,-out-implib,bin/libcore.dll.a).

Eu passo LDFLAGSpara meu Makefile da seguinte maneira:

make -f build/Makefile  PLATFORM="linux" \
                        TARGET="bin/libcore.so" \
                        LDFLAGS="-shared" \
                        ... \

e em build/Makefile, tenho as seguintes linhas que fazem referência LDFLAGSa:

# Linker flags.
ifeq ($(PLATFORM),linux)
    LDFLAGS += -Wl,-rpath,bin
endif
ifeq ($(suffix $(TARGET)),.dll)
    LDFLAGS += -Wl,--out-implib,$(dir $(TARGET))lib$(basename $(notdir $(TARGET))).dll.a
endif

# Build target.
$(TARGET): $(OBJ_FILES)
    $(CC) -o $@ $^ $(LDFLAGS)

Mas quando tento executar o Makefile, recebo:

LDFLAGS += -Wl,-rpath,bin
make[1]: LDFLAGS: No such file or directory

Solução

Conforme observado na resposta aceita, a sintaxe do meu Makefile estava incorreta. Além disso, atualizei rpathpara $$ORIGINem vez de binpara evitar os problemas descritos na resposta. Aqui está o Makefile funcionando:

# Additional linker flags.
EXTRA_LDFLAGS :=
ifeq ($(PLATFORM),linux)
EXTRA_LDFLAGS := -Wl,-rpath,'$$ORIGIN'
endif
ifeq ($(suffix $(TARGET)),.dll)
EXTRA_LDFLAGS := -Wl,--out-implib,$(dir $(TARGET))lib$(basename $(notdir $(TARGET))).dll.a
endif

# Build target.
$(TARGET): $(OBJ_FILES)
    $(CC) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS)
gcc
  • 1 respostas
  • 30 Views
Martin Hope
Oh Fiveight
Asked: 2024-05-19 04:19:33 +0800 CST

Depurando uma operação errônea de 'inserção' de árvore AVL

  • 6

Estou tentando criar uma estrutura de dados em árvore AVL que possa lidar com chaves de elementos duplicadas. Baseei meu algoritmo de inserção no seguinte: https://www.sanfoundry.com/c-program-implement-avl-tree/#google_vignette .

No entanto, minha avl_tree_insertimplementação parece não conseguir lidar com certas chaves duplicadas e não sei por quê; basicamente, determinei que a inserção funciona a menos que todas as condições a seguir sejam atendidas* (*Isso vem do meu próprio entendimento das verificações realizadas pelo meu código, combinadas com a saída de depuração. Pode ser uma lógica defeituosa, conforme observado por pelo menos um comentário. Leia o código para detalhes reais):

  1. A chave inserida já existe na árvore.
  2. O nó raiz possui campos nulos lefte rightfilhos.
  3. O nó raiz está desequilibrado (o que significa que é necessária uma rotação para a direita no nó raiz).
  4. A chave que está sendo inserida é maior ou igual à chave à esquerda da raiz (o que significa que é necessária uma rotação para a esquerda no nó esquerdo).

Quando o código verifica 4, uma rotação para a esquerda no nó esquerdo é invocada, que falha devido a uma desreferência de ponteiro nulo (porque ( *root ).lefte ( *root ).rightsão nulos, consulte 2).

O que me confunde é como descobrir como esse estado de árvore realmente surge e como corrigi-lo; por exemplo, invocar avl_tree_insertcom chaves aleatórias geralmente funciona centenas ou milhares de vezes, para muitos estados aleatórios diferentes da árvore, mas de repente a árvore atinge um estado como o descrito acima e tudo falha abruptamente; é isso que não sei depurar.

Abaixo está um código de driver de teste que causará uma falha ao usar avl_tree_insertoperações. Tentei incluir todas as partes relevantes da estrutura de dados em árvore e do algoritmo de inserção abaixo, omitindo qualquer coisa estranha, e também incluí algumas instruções de depuração de impressão.

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

// Adjust for your hardware.
typedef unsigned long long int  u64;
typedef signed long long int    i64;
typedef signed short int        i16;

/** @brief Type and instance definitions for generic boolean type. */
typedef _Bool bool;
#define true    ( ( bool ) 1 )
#define false   ( ( bool ) 0 )

/** @brief Type definition for an AVL tree node. */
typedef struct node_t
{
    i64             key;
    u64             depth;

    struct node_t*  left;
    struct node_t*  right;

    void*           content;
}
node_t;

/** @brief Type definition for an AVL tree. */
typedef struct
{
    u64         element_width;
    u64         element_count;

    u64         node_count;
    node_t*     root;
}
avl_tree_t;

// Global op count.
static u64 op_count = 0;

// Global debug flag.
static bool debug_flag;

bool
avl_tree_create
(   u64             element_width
,   avl_tree_t**    tree_
)
{
    if ( !element_width )
    {
        printf ( "avl_tree_create: Value of element_width argument must be non-zero.\n" );
        return false;
    }
    if ( !tree_ )
    {
        printf ( "avl_tree_create: Missing argument: tree (output buffer).\n" );
        return false;
    }

    avl_tree_t* tree = malloc ( sizeof ( avl_tree_t ) );
    tree->element_width = element_width;
    tree->element_count = 0;
    tree->node_count = 0;
    tree->root = 0;
    
    *tree_ = tree;
    return true;
}

u64
avl_tree_recompute_depth
(   node_t* root
)
{
    u64 left;
    u64 right;
    
    if ( !root )
    {
        return 0;
    }

    if ( !root->left )
    {
        left = 0;
    }
    else
    {
        left = 1 + root->left->depth;
    }

    if ( !root->right )
    {
        right = 0;
    }
    else
    {
        right = 1 + root->right->depth;
    }

    return ( left > right ) ? left : right;
}

i64
avl_tree_balance_factor
(   node_t* root
)
{
    u64 left;
    u64 right;
    
    if ( !root )
    {
        return 0;
    }

    if ( !root->left )
    {
        left = 0;
    }
    else
    {
        left = 1 + root->left->depth;
    }

    if ( !root->right )
    {
        right = 0;
    }
    else
    {
        right = 1 + root->right->depth;
    }

    return left - right;
}

node_t*
avl_tree_rotate_left
(   node_t* root
)
{
    // Rotate left.
    node_t* right = root->right;
    if ( !right ) printf ( "Failure on append #%llu. No node to the right of %i.\n" , op_count , root->key );
    root->right = right->left;
    right->left = root;

    // Update depth.
    root->depth = avl_tree_recompute_depth ( root );
    right->depth = avl_tree_recompute_depth ( right );

    return right;
}

node_t*
avl_tree_rotate_right
(   node_t* root
)
{
    // Rotate right.
    node_t* left = root->left;
    if ( !left ) printf ( "Failure on append #%llu. No node to the left of %i.\n" , op_count , root->key );
    root->left = left->right;
    left->right = root;

    // Update depth.
    root->depth = avl_tree_recompute_depth ( root );
    left->depth = avl_tree_recompute_depth ( left );

    return left;
}

node_t*
_avl_tree_insert
(   avl_tree_t* tree
,   node_t*     root
,   const void* src
,   const i64   key
)
{
    // CASE: End of branch.
    if ( !root )
    {
        // Initialize a new element node.
        node_t* node = malloc ( sizeof ( node_t ) + tree->element_width );
        memset ( node , 0 , sizeof ( node_t ) );
        ( *node ).key = key;
        ( *node ).content = ( void* )( ( ( u64 ) node ) + sizeof ( node_t ) );
        memcpy ( node->content , src , tree->element_width );

        // Insert the node into the tree.
        root = node;

        // Update state.
        tree->node_count += 1;
        tree->element_count += 1;
    }

    // CASE: Key > root key (recurse right).
    else if ( key > root->key )
    {
        root->right = _avl_tree_insert ( tree
                                       , root->right
                                       , src
                                       , key
                                       );

        // Rebalance? Y/N
        if ( avl_tree_balance_factor ( root ) < -1 )
        {
            if ( key <= root->right->key )
            {
                root->right = avl_tree_rotate_right ( root->right );
            }
            root = avl_tree_rotate_left ( root );
        }
    }

    // CASE: Key <= root key (recurse left).
    else
    {
        if ( key == root->key )
        {
            debug_flag = true;
            printf ( "Keys match: %i, left key: %i, right key: %i\n"
                   , key
                   , ( root->left ? root->left->key : -1 )
                   , ( root->right ? root->right->key : -1 )
                   );
        }
        root->left = _avl_tree_insert ( tree
                                      , root->left
                                      , src
                                      , key
                                      );

        // Rebalance? Y/N
        if ( avl_tree_balance_factor ( root ) > 1 )
        {
            if ( key >= root->left->key )
            {
                if ( debug_flag ) printf ("Rotate left required.\n" );
                root->left = avl_tree_rotate_left ( root->left );
            }
            root = avl_tree_rotate_right ( root );
        }
    }
    
    root->depth = avl_tree_recompute_depth ( root );
    return root;
}

void
avl_tree_insert
(   avl_tree_t* tree
,   const void* src
,   const i64   key
)
{
    debug_flag = false;
    tree->root = _avl_tree_insert ( tree
                                  , tree->root
                                  , src
                                  , key
                                  );
}

// Test driver.
int
main
( void )
{
    srand ( time ( 0 ) );

    avl_tree_t* tree;
    avl_tree_create ( sizeof ( i16 ) , &tree );

    for ( u64 i = 0; i < 1000000; ++i )
    {
        i16 key;
        do
        {
            key = rand ();
        }
        while ( key == -1 );
        op_count += 1;
        avl_tree_insert ( tree , &key , key ); // Value can just be same as key here.
    }
    printf ( "Num elements in tree: %llu\n" , tree->element_count );

    return 0;
}

Exemplo de saída (-1 indica chave nula):

Keys match: 2214, left key: -1, right key: -1
Keys match: 5145, left key: -1, right key: -1
Keys match: 7141, left key: -1, right key: -1
Keys match: 16453, left key: -1, right key: -1
Keys match: 15365, left key: -1, right key: -1
Keys match: 22779, left key: 22764, right key: 22816
Keys match: 11855, left key: -1, right key: -1
Rotate left required.
Failure on append #857. No node to the right of 11855.
// (OS crashes the program)
c
  • 1 respostas
  • 55 Views
Martin Hope
Oh Fiveight
Asked: 2023-12-14 02:30:09 +0800 CST

C: macro de pré-processador para construir e usar literais de string em tempo de compilação?

  • 5

Eu tenho uma função C que estou usando para formatar strings que possui a seguinte assinatura:

int
string_format
(   char*       dst
,   const char* fmt
,   ...
);

Eu costumo chamá-lo assim:

char buf[20];
const char* name = "Jeff";
string_format ( buf , "Hello %s!\n" , name );

Agora estou tentando trabalhar com texto colorido usando códigos de cores ANSI. Idealmente, quero usá-los em meus literais de string assim:

char buf[20];
const char* name = "Jeff";
string_format ( buf , COLOR_RED "Hello %s!\n" , name );

Escrevi algumas macros para construir essas strings literais, mas fiz algo errado. Por exemplo, eu tentei:

#define ANSI_CC(color) "\033["#color"m"
#define ANSI_CC_FG_RED "91"

#define COLOR_RED (ANSI_CC(ANSI_CC_FG_RED))

Mas quando tento chamar string_format (buf, COLOR_RED "Hello world.\n""), recebo um erro do compilador:

error: expected ')' before string constant
    |     COLOR_RED "Hello world.\n"
                    ^~~~~~~~~~~~~~~~

Meu pensamento era que o pré-processador avaliaria COLOR_REDisso:

COLOR_RED                 =>
(ANSI_CC(ANSI_CC_FG_RED)) =>
"\033["ANSI_CC_FG_RED"m"  =>
"\033[""91""m"

Mas obviamente está fazendo outra coisa, que não entendo; Suspeito que usei o #operador stringify incorretamente. Alguém poderia explicar o que o pré-processador está fazendo com as macros que escrevi? Além disso, se o que desejo realizar for possível, o que preciso mudar?

Obrigado.

c
  • 1 respostas
  • 39 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve