【问题标题】:Convert Vectors of C++ to C将 C++ 的向量转换为 C
【发布时间】:2019-07-17 10:46:07
【问题描述】:

我正在尝试转换矢量vectorName;对 C 的 cpp 实现 实际上我必须在 C 中使用它的一些函数,比如 vectorName.push_back(string) 但是我该怎么做没有正确的实现,有什么方法可以使用 c++ 库并以某种方式将其修补到 C 代码中,这是我的想法

typedef struct vector_ {
      void** data;
      int size;
      int count;
} vector;

void vector_add(vector*, void*);
void vector_add(vector *v, void *e)
{
    if (v->size == 0) {
        v->size = 10;
        v->data = malloc(sizeof(void*) * v->size);
        memset(v->data, '\0', sizeof(void*) * v->size);
    }

    if (v->size == v->count) {
        v->size *= 2;
        v->data = realloc(v->data, sizeof(void*) * v->size);
    }

    v->data[v->count] = e;
    v->count++;
}

【问题讨论】:

  • std::vector 严重依赖 C++ 特性,例如 C 根本没有的复制构造(当然还有模板)。我不认为这会飞。
  • 我知道 c dosent 具有这些功能,这就是为什么我首先在​​链表中这样做
  • 你想实现一个等效的std::vector<T>::push_back()(通用)或std::vector<SomeSpecificType>::push_back(),你知道存储的时间类型吗?
  • 主要问题是关于数据的类型,如果为每种需要的类型都有一个专用的 vector_xx 会更安全。请注意,您可以使用宏来定义适当的vector_xx,而不必每次都手动进行
  • 我正在尝试实现 SomeSpecificType 例如我希望数据类型是字符@BoR

标签: c++ c arrays linked-list


【解决方案1】:

一个例子:

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

#define DEF_VECTOR(type) \
typedef struct vector_##type { \
  type * data; \
  size_t alloc_size; \
  size_t size; \
} vector_##type; \
\
void init_vector_##type(vector_##type * vector) \
{ \
  vector->data = NULL; \
  vector->alloc_size = vector->size = 0; \
} \
\
void clear_vector_##type(vector_##type * vector) \
{ \
  if (vector->data != NULL) {\
    free(vector->data); \
    init_vector_##type(vector);  \
  } \
} \
\
void push_back_vector_##type(vector_##type * vector, type value) \
{ \
  if (vector->size == vector->alloc_size) { \
    vector->alloc_size = (vector->alloc_size == 0) ? 16 : vector->alloc_size * 2; \
    vector->data = realloc(vector->data, vector->alloc_size * sizeof(type)); \
     \
    if (vector->data == NULL) { \
      /* do what you want */ \
    } \
  } \
  vector->data[vector->size++] = value; \
} \
\
type at_vector_##type(vector_##type * vector, size_t index) \
{ \
  if (index >= vector->size) { \
    /* do what you want */ \
  } \
  return vector->data[index]; \
}

DEF_VECTOR(int)

int main()
{
  vector_int v;

  init_vector_int(&v);
  push_back_vector_int(&v, 123);
  push_back_vector_int(&v, 456);
  printf("%d %d\n", at_vector_int(&v, 0), at_vector_int(&v, 1));
  printf("%d %d\n", v.data[0], v.data[1]);
  clear_vector_int(&v);
  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra v.c
pi@raspberrypi:/tmp $ ./a.out
123 456
123 456

valgrind下执行

pi@raspberrypi:/tmp $ valgrind ./a.out
==11108== Memcheck, a memory error detector
==11108== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11108== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11108== Command: ./a.out
==11108== 
123 456
123 456
==11108== 
==11108== HEAP SUMMARY:
==11108==     in use at exit: 0 bytes in 0 blocks
==11108==   total heap usage: 2 allocs, 2 frees, 1,088 bytes allocated
==11108== 
==11108== All heap blocks were freed -- no leaks are possible
==11108== 
==11108== For counts of detected and suppressed errors, rerun with: -v
==11108== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

当然,你必须不要忘记调用init_vector_xx,如果需要clear_vector_xx,当你因为没有行号等而在执行时出现错误时,使用宏来定义所有这些都无济于事

这里我把所有的都放在唯一的宏里,实际上最好有一个宏来定义struct并声明函数,另外一个来定义函数,这样就可以把在标题和来源中。

有什么方法可以使用 c++ 库并以某种方式将其修补到 C 代码中

不确定是否可以回答该问题。当然,您可以从他们的定义中得到一些想法,因为它们实施得很好,但您也冒着被翻译中不需要的复杂性所淹没的风险。

但是,如果您可以留在 C++ 中,请不要转向 C ;-)

【讨论】:

    【解决方案2】:

    如果您想要类似于std::vector&lt;char&gt; 的东西,那么等效的push_back(char ch) 解决方案建议可能是:

    #include <stdlib.h>
    #include <stdio.h>
    
    typedef struct vectorOfChar vector;
    struct vectorOfChar {
        char *start;
        char *finish;
        char *end_of_storage;
    };
    
    vector vector_construct(void) {
        vector v = {0};
        return v;
    }
    
    void vector_destruct(vector *const vec) {
        free(vec->start);
    }
    
    char *vector_data(vector *const vec) {
        return vec->start;
    }
    
    void vector_push_back(vector *const vec, char const ch) {
        if (vec->finish != vec->end_of_storage) {
            *vec->finish = ch;
            ++vec->finish;
        } else {
            int const size = vec->finish - vec->start;
            int capacity = vec->end_of_storage - vec->start;
            capacity++;
            capacity *= 3;
            capacity /= 2;
            char *const new_area = realloc(vec->start, capacity);
            if (new_area == NULL) {
                // define how to handle out-of-memory
                exit(EXIT_FAILURE);
            }
            vec->start = new_area;
            vec->finish = new_area + size;
            vec->end_of_storage = new_area + capacity;
            vector_push_back(vec, ch);
        }
    }
    
    int main() {
        vector v = vector_construct();
    
        for (char c = 'a'; c <= 'z'; c++) {
            vector_push_back(&v, c);
        }
        vector_push_back(&v, '\0');
    
        printf("%s\n", vector_data(&v));
    
        vector_destruct(&v);
    
        return EXIT_SUCCESS;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-10
      • 2011-09-17
      • 2023-04-07
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      相关资源
      最近更新 更多