小编het*_*fan的帖子

如何使用带有指向不应释放的struct的指针的shared_ptr

目前我正在使用glib库中的一些函数.随着glib也来了gio.glib是一个C库,因此我需要删除一些我创建的结构.

对于我创建智能指针的许多对象,例如:

std::shared_ptr<GAsyncQueue> my_queue = std::shared_ptr<GAsyncQueue>(g_async_queue_create(), g_async_queue_unref);
Run Code Online (Sandbox Code Playgroud)

为此创建了一个指向a的共享指针GAsyncQueue,这可以安全地在其生​​命周期结束时销毁队列.

但是,当我从gio库获取一个我不应该释放的指针时遇到问题.在下面的代码中my_connection是一个GSocketClient,它实现了(在glib中)GIOStream.

std::shared_ptr<GInputStream> my_input_stream = 
     std::shared_ptr<GInputStream> (
        g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get()))
     );
Run Code Online (Sandbox Code Playgroud)

因为GIOStream上的文档提到,g_io_stream_get_input_stream()不应释放获得的指针.那是因为它归my_connection实例所有.我想为destroy对象创建一个lamda,它是共享指针对象的第二个参数.例如auto deleter = [](GInputStream* ptr) {};,然后将lambda作为detroy函数提供给共享指针,但这感觉有点愚蠢.

c++ pointers shared-ptr c++11

16
推荐指数
3
解决办法
2078
查看次数

C中的无限递归

给定具有无限递归的C程序:

int main() {

    main();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么会导致堆栈溢出.我知道这导致C++中来自以下线程的未定义行为这是无限递归UB吗?(并且作为无法main()在C++中调用的副节点).但是,valgrind告诉我这会导致堆栈溢出:

Stack overflow in thread 1: can't grow stack to 0x7fe801ff8
Run Code Online (Sandbox Code Playgroud)

最后由于分段错误,程序结束:

==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907==  Access not within mapped region at address 0x7FE801FF0
Run Code Online (Sandbox Code Playgroud)

这是C中的未定义行为,还是应该导致堆栈溢出,为什么会导致堆栈溢出?

编辑

1我想知道C中是否允许无限递归?
2这是否会导致堆栈溢出?(已经得到了充分的回答)

c recursion

13
推荐指数
3
解决办法
1万
查看次数

麻烦使用CMake链接到Windows上的静态库

LS,

我正在尝试建立一个静态和动态库,该库可用于动态和静态链接。我希望该库能够在尽可能多的平台上运行,无论使用哪种编译器。为了构建库和一些测试程序,我使用CMake在Linux和Windows上分别使用g ++和MSVC ++来构建库eeg。

在Linux上,动态库和静态库似乎都可以像我所怀疑的那样工作;在Windows上,.dll似乎可以完美链接,并且我的测试程序可以运行。但是,使用静态库的程序会抱怨链接错误。我真的很想念我做错了什么,这可能在我的CMakeLists.txt中,也可能在我的库的设置中。下面,我做了一个最小的程序,该程序使用我的库来演示我遇到的问题。该库包含两个C ++文件,一个用于导出C ++文件中的代码的C API,一个使用C API的C ++程序以及一个最终的CMakeList.txt,它可以构建除使用静态库的程序之外的所有程序。这一切都产生了一个奇妙的“你好,世界!”。

我知道我展示了很多代码,但是至少这是一个最小的项目,它演示了我链接到静态库的问题。我希望有人足够友善地看一下这个项目,并向我解释我做错了什么。

亲切的问候,

Hetepeperfan

C ++文件PriCpp.cpp

#include "PriCpp.h"

using namespace std;
string PriMessageBuilder::message() const {
    return "Hello, World!";
}
Run Code Online (Sandbox Code Playgroud)

头文件PriCpp.h

#ifndef PRICPP_H
#define PRICPP_H

#include <string>

class PriMessageBuilder{
public:
    std::string message() const;
};

#endif
Run Code Online (Sandbox Code Playgroud)

C API是:mycapi.h

#ifndef MYCAPI_H
#define MYCAPI_H
#include "builder_export.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {} message_builder;

BUILDER_EXPORT message_builder* message_builder_new();
BUILDER_EXPORT void             message_builder_destroy(
                                        message_builder* builder
                                        );
BUILDER_EXPORT char*            message_builder_message(
                                        message_builder* builder
                                        );
#ifdef __cplusplus
}
#endif …
Run Code Online (Sandbox Code Playgroud)

c c++ cmake static-libraries libraries

6
推荐指数
1
解决办法
3034
查看次数

GtkEntry 更改用户输入的文本

在 gui 中,我想修改用户在 GtkEntry 中插入的文本。例如,如果用户输入“joHn doe”,我的 gui 应该会看到这不是一个格式良好的名称,并将其更改为“John Doe”。

我将 a 处理程序连接到“已更改”信号,如GtkEntry 文本更改信号中所述。出现的问题是,如果我更改信号处理程序中的条目,“已更改”信号会一次又一次地发出,直到王国来临。

我目前通过进行字符串比较来防止这种情况,如果文本“namified”版本与条目内的文本不相等,我只会更改 GtkEntryBuffer 中的文本。但是,我觉得作为程序员,我应该能够更改条目内的文本,而无需一遍又一遍地调用更改后的处理程序。

更改后的信号处理程序是:

void nameify_entry ( GtkEditable* editable, gpointer data )
{
    gchar* nameified;
    const gchar *entry_text;

    entry_text = gtk_entry_get_text( GTK_ENTRY(editable) );
    nameified = nameify(entry_text);

    /*is it possible to change the buffer without this using this string
      comparison, without the "change" signal being emitted over and over again?*/
    if ( g_strcmp0(entry_text, nameified) != 0 ){
        GtkEntryBuffer* buf = gtk_entry_get_buffer(GTK_ENTRY(editable) );
        gtk_entry_buffer_set_text( buf, nameified, -1 …
Run Code Online (Sandbox Code Playgroud)

gtk user-interface

5
推荐指数
1
解决办法
5740
查看次数

如何获得 etree._Element 的以下兄弟姐妹

我正在迭代我在 xml 文件中找到的元素,如下所示:

for elem in fileasxml.xpath("//elementname[some condition]"):
    do something
Run Code Online (Sandbox Code Playgroud)

现在,do something我不想将我找到的元素加上第一个以下兄弟姐妹写入文件。现在我知道如何写入文件,我不知道如何获得以下兄弟。

我已经看到了该getnext()方法,但它不起作用,因为我想要获取的元素不在elem.

同样的原因我不能使用 elem.xpath()

有任何想法吗 ?

python lxml python-2.7 xml.etree

5
推荐指数
1
解决办法
7819
查看次数

std::remove_if 不会删除所有项目

在输入中我想删除所有非唯一值。我希望删除双项后的子集与输入相同。不知何故,某些字符保留在输入中,但并非所有字符都被删除。谓词内的 std::map 的大小似乎也在减小。

我使用的 std::remove_if() 谓词是:

template<class T>
class RemovePredicate {

    public:

        RemovePredicate() : m_oldsize(0) {}

        bool operator()(const T& value)
        {
            //
            bool retval;
            m_uniques[value] ='a'; // 'a' could be any value
            cout << m_uniques.size() << endl;
            retval = m_uniques.size() == m_oldsize;
            m_oldsize = m_uniques.size();
            return retval;
        }

    private:

        std::map<T, char>   m_uniques;
        unsigned            m_oldsize;

};
Run Code Online (Sandbox Code Playgroud)

我设计谓词的方式是,当我看到大小增加时,我还没有遇到输入。因此,当大小不同时,我不会删除输入。当大小保持不变时,我再次遇到该输入值,然后我将其删除。

测试这个的代码是:

template<class T>
void print(T iterable)
{
    for (auto c : iterable)
        cout << c;
    cout << endl;
}


int main(int argc, char** argv){ …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm

5
推荐指数
1
解决办法
448
查看次数

调试 c 扩展时从 gdb 中的 pdb 进行单步调试

我正在为 python 开发 C(++) 扩展。我有一个 C 语言库,我使用 Swig 包装它。不幸的是,我想调试 C 扩展中的一些错误。我的程序大量使用通过串行连接发送的 MsgBuffer 类。所有消息可能包含多个部分。如果我将 MsgPart 添加到 MsgBuffer,那么 msg 应该复制消息,但目前看起来我正在添加引用,因为一旦我修改了该部分,添加修改后的部分,初始部分看起来就像这样也被修改。

所以我想做的是在我的 python 程序中设置一个断点并单步执行调试器。

pin = 12  # Pin 12 on Teensy3.2
pullup = False  # No need for enabling pull up resistor.
msg = MsgBuffer(TEENSY_REQ_INPUT_PIN)
part= MsgPart()
part.write_uint32(pin)
msg.add_part(part)
part.write_uint32(1 if pullup else 0)
msg.add_part(part) # I would like to set a breakpoint here in order to see whether it is added as reference or it is copied in the c extension …
Run Code Online (Sandbox Code Playgroud)

c python swig python-extensions

5
推荐指数
0
解决办法
677
查看次数

是否允许在类构造函数之外初始化非静态成员?

我刚看到一个问题,其中类的非静态成员在类定义中初始化.但是,如果我尝试编译以下代码,我会从编译器中收到错误.

class MyClass
{
    int n = 2;
};
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

g++ -o ns nonstatic.cpp -Wall -Wextra -pedantic
nonstatic.cpp:3:13: error: ISO C++ forbids initialization of member ‘n’ [-fpermissive]
nonstatic.cpp:3:13: error: making ‘n’ static [-fpermissive]
nonstatic.cpp:3:13: error: ISO C++ forbids in-class initialization of non-const static member ‘n’
Run Code Online (Sandbox Code Playgroud)

我一直以为我必须在构造函数中初始化这样的成员,如下所示:

class MyClass
{
    public:
        MyClass ( void ) : n(2) {}
    private:
        int n;
};
Run Code Online (Sandbox Code Playgroud)

或者n在构造函数体内初始化.所以我的问题是:什么时候允许在类构造函数的上下文之外初始化一个非静态成员?

亲切的问候,

c++ initialization

4
推荐指数
1
解决办法
1909
查看次数

类似函数的宏和枚举器具有相同的名称

在下面的片段中struct IndexError,当用户使用我的库出错时,我将返回一个片段。我有一个类似于函数的宏,该宏将指针转换为IndexError*,而一个枚举都称为INDEX_ERROR

enum errors {
    SUCCESS,
    INVALID_ARGUMENT,
    INDEX_ERROR
};

struct Error {
    char error_buff[BUFSIZ];
};

typedef struct Error Error;

struct IndexError {
    Error  parent;
    size_t invalid_index;
    // etc.
};

typedef struct IndexError IndexError;


#define INDEX_ERROR(obj) ((IndexError*) obj)
Run Code Online (Sandbox Code Playgroud)

我将如何使用此示例:

size_t pos = 4;
int IndexPointer* error = NULL;
int status = array_remove_item(my_array, pos, &error);
Run Code Online (Sandbox Code Playgroud)

然后,我检查状态。如果它没有返回SUCCESS,我将检查该错误,因为那应该指向一个新创建的错误。

数组函数之一的实现可能如下所示:

int array_remove_item(Array* array, size_t pos, Error** error_out)
{
    Error* error = NULL;
    if(pos >= array->size) {
        index_error_create(INDEX_ERROR(&error), …
Run Code Online (Sandbox Code Playgroud)

c macros c-preprocessor

3
推荐指数
1
解决办法
78
查看次数

python list comprehension vs + =

今天我试图找到一个方法,在python中对字符串进行一些处理.一些比我说的高级程序员不使用+=但使用''.join()我也可以在例如http://wiki.python.org/moin/PythonSpeed/#Use_the_best_algorithms_and_fastest_tools中阅读.但是我自己测试了这个并且发现了一些奇怪的结果(这不是我想要再猜测它们但是我想要站立).想法是,如果有一个"This is \"an example text\"包含空格的字符串"字符串应该被转换为Thisis"an example text"containingspaces空格被删除,但只在引号之外.

我测量了我的算法的两个不同版本的性能,使用了''.join(list)一个和一个+=

import time

#uses '+=' operator
def strip_spaces ( s ):
    ret_val = ""
    quote_found = False
    for i in s:
        if i == '"':
            quote_found = not quote_found

        if i == ' ' and quote_found == True:
            ret_val += i

        if i != ' ':
            ret_val += i
    return ret_val

#uses "".join ()   
def strip_spaces_join ( s ):
    #ret_val …
Run Code Online (Sandbox Code Playgroud)

python performance list-comprehension augmented-assignment

2
推荐指数
1
解决办法
1115
查看次数