目前我正在使用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程序:
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这是否会导致堆栈溢出?(已经得到了充分的回答)
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) 在 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) 我正在迭代我在 xml 文件中找到的元素,如下所示:
for elem in fileasxml.xpath("//elementname[some condition]"):
do something
Run Code Online (Sandbox Code Playgroud)
现在,do something我不想将我找到的元素加上第一个以下兄弟姐妹写入文件。现在我知道如何写入文件,我不知道如何获得以下兄弟。
我已经看到了该getnext()方法,但它不起作用,因为我想要获取的元素不在elem.
同样的原因我不能使用 elem.xpath()
有任何想法吗 ?
在输入中我想删除所有非唯一值。我希望删除双项后的子集与输入相同。不知何故,某些字符保留在输入中,但并非所有字符都被删除。谓词内的 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) 我正在为 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) 我刚看到一个问题,其中类的非静态成员在类定义中初始化.但是,如果我尝试编译以下代码,我会从编译器中收到错误.
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在构造函数体内初始化.所以我的问题是:什么时候允许在类构造函数的上下文之外初始化一个非静态成员?
亲切的问候,
在下面的片段中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) 今天我试图找到一个方法,在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)