- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在使用 Boost 共享指针时遇到了一些问题。指针指向的数据在不确定的时间突然被删除。在当前程序中(我尝试过许多其他变体)boost::shared_array<TableFieldsMap> retArray
的数据案例后在switch构造中突然被删除MYSQL_TYPE_DOUBLE
这种情况下,在循环恰好运行了 172 行之后(表中有 1000 行)。但仅当该方法被调用两次时。第一次运行非常完美。
具体来说,我指出问题出在分配给 retArray 时使用的映射键。当我使用硬编码字符串时它起作用了。但不是局部 shared_array (fieldNameArray) 的值(我首先有 scoped_array,但据我所知这不应该起作用),也不是局部变量 (tmpIndex)。
retArray[rowIndex]["value"] = boost::lexical_cast<long double>(row[i]); // This works.
// This doesn't work: retArray[rowIndex][fieldNameArray[i]] = boost::lexical_cast<long double>(row[i]);
// This doesn't work either: retArray[rowIndex][tmpIndex.c_str()] = boost::lexical_cast<long double (row[i]);
这是标题类:
#ifndef DATABASE_H
#define DATABASE_H
#include <map>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
#include <glog/logging.h>
#include <boost/lexical_cast.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/variant.hpp>
#include <mysql.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include "../globals/globals.hpp"
#include "../exception/cassandra_exception.hpp"
struct mapCompare
{
bool operator()(char const * a, char const * b)
{
return (strcmp(a, b) < 0);
}
};
typedef map<const char*, boost::variant<short, int, long double, char*>, mapCompare > TableFieldsMap;
struct DataSet
{
unsigned int rowCount;
boost::shared_array<TableFieldsMap>data;
};
class Database
{
private:
MYSQL *connection;
public:
Database();
~Database();
bool connect(const char *, const char *, const char *, const char *);
DataSet select(const char*);
};
#endif
和代码:
#include "database.hpp"
Database::Database()
{
DLOG(INFO) << "::Database";
}
Database::~Database()
{
DLOG(INFO) << "~Database";
if (connection) mysql_close(connection);
}
bool Database::connect(const char* server, const char* user, const char* password, const char* database)
{
DLOG(INFO) << ">> connect";
connection = mysql_init(NULL);
if (!connection)
{
cout << "Error" << endl;
return (false);
}
if (!mysql_real_connect(connection, server, user, password, database, 0, NULL, 0))
{
cout << "Database init error (" << mysql_error(connection) << ")" << endl;
}
if (!connection)
{
cout << "Connection Failed!" << endl;
return (false);
}
return (true);
}
DataSet Database::select(const char* query)
{
DLOG(INFO) << ">> select";
MYSQL_RES *resultSet;
MYSQL_ROW row;
unsigned int fieldCount;
MYSQL_FIELD* field;
// Query database.
if (mysql_query(connection, query)) throw MyException(string("Database select error (") + mysql_error(connection) + ")");
// Handle result-set.
resultSet = mysql_store_result(connection);
if (resultSet == NULL) throw MyException(string("Database select error. Result-set is empty (") + mysql_error(connection) + ")");
// Initialize return array.
unsigned int rowCount = mysql_num_rows(resultSet);
boost::shared_array<TableFieldsMap> retArray(new TableFieldsMap[rowCount]);
// Obtain field names and types.
fieldCount = mysql_num_fields(resultSet);
boost::shared_array<const char *> fieldNameArray(new const char* [fieldCount]);
boost::scoped_array<enum_field_types> fieldTypeArray(new enum_field_types[fieldCount]);
unsigned int fieldIndex = 0;
while ((field = mysql_fetch_field(resultSet)))
{
fieldNameArray[fieldIndex] = field -> name;
fieldTypeArray[fieldIndex++] = field -> type;
}
// Fix?
string tmpIndex;
// Load data from result-set.
unsigned int rowIndex = 0;
while ((row = mysql_fetch_row(resultSet)) != NULL)
{
// Fields of the row.
for (unsigned int i = 0; i < fieldCount; i++)
{
if (row[i] == NULL) throw MyException("Database error. Null.");
switch (fieldTypeArray[i])
{
// Medium int & Integer.
case MYSQL_TYPE_INT24 :
case MYSQL_TYPE_LONG :
retArray[rowIndex][fieldNameArray[i]] = boost::lexical_cast<int>(row[i]);
break;
case MYSQL_TYPE_DOUBLE :
try
{
retArray[rowIndex]["value"] = boost::lexical_cast<long double>(row[i]); // This works.
}
catch (boost::bad_lexical_cast exception)
{
DLOG(ERROR) << "Error reading the phi table from database. Cast error. (" << rowIndex << ", " << row[i] << ")" << endl;
throw MyException("Error reading the phi table from database. Cast error.");
}
// tmpIndex = string(fieldNameArray[i]);
// This doesn't work: retArray[rowIndex][fieldNameArray[i]] = boost::lexical_cast<long double>(row[i]);
// This doesn't work either: retArray[rowIndex][tmpIndex.c_str()] = boost::lexical_cast<long double>(row[i]);
break;
case MYSQL_TYPE_VARCHAR : // 15
case MYSQL_TYPE_VAR_STRING : // 253
case MYSQL_TYPE_STRING : // 254
retArray[rowIndex][fieldNameArray[i]] = row[i];
break;
case MYSQL_TYPE_DECIMAL : // 0
case MYSQL_TYPE_TINY : // 1
case MYSQL_TYPE_SHORT : // 2
case MYSQL_TYPE_FLOAT : // 4
case MYSQL_TYPE_NULL : // 6
case MYSQL_TYPE_TIMESTAMP : // 7
case MYSQL_TYPE_LONGLONG : // 8
case MYSQL_TYPE_DATE : // 10
case MYSQL_TYPE_TIME : // 11
case MYSQL_TYPE_DATETIME : // 12
case MYSQL_TYPE_YEAR : // 13
case MYSQL_TYPE_NEWDATE : // 14
case MYSQL_TYPE_BIT : // 16
case MYSQL_TYPE_NEWDECIMAL : // 246
case MYSQL_TYPE_ENUM : // 247
case MYSQL_TYPE_SET : // 248
case MYSQL_TYPE_TINY_BLOB : // 249
case MYSQL_TYPE_MEDIUM_BLOB : // 250
case MYSQL_TYPE_LONG_BLOB : // 251
case MYSQL_TYPE_BLOB : // 252
default:
DLOG(FATAL) << "Database error. Unsupported datatype";
throw MyException("Database error. Unsupported datatype");
break;
}
rowIndex++;
}
}
mysql_free_result(resultSet);
DataSet retStruct;
retStruct.rowCount = rowCount;
retStruct.data = retArray;
return (retStruct);
}
...
调用方法如下:
include "My_database.hpp"
MyDatabase::MyDatabase(string server, string user, string password, string database)
{
DLOG(INFO) << "::MyDatabase (1)";
init(server.c_str(), user.c_str(), password.c_str(), database.c_str());
}
MyDatabase::MyDatabase(const char* server, const char* user, const char* password, const char* database)
{
DLOG(INFO) << "::MyDatabase (2)";
init(server, user, password, database);
}
MyDatabase::~MyDatabase()
{
DLOG(INFO) << "~MyDatabase";
}
void MyDatabase::init(const char* server, const char* user, const char* password, const char* database)
{
DLOG(INFO) << ">> init";
connect(server, user, password, database);
}
boost::shared_array<long double>MyDatabase::loadPhiTable()
{
DLOG(INFO) << ">> LoadPhiTable";
// Select from database.
DataSet selectData = select("SELECT value FROM phi");
boost::shared_array<TableFieldsMap>phiArray = selectData.data;
unsigned int rowCount = selectData.rowCount;
// Initialize return array.
boost::shared_array<long double> retArray(new long double[rowCount]);
unsigned int i = 0;
try
{
for (i = 0; i < rowCount; i++) retArray[i] = boost::get<long double>(phiArray[i]["value"]);
}
catch (boost::bad_get exception)
{
throw MyException(string("Error reading the phi table. Conversion error. (index: ") + boost::lexical_cast<string>(i) + ", value: " + boost::lexical_cast<string>(phiArray[i]["value"]) + ")");
}
return (retArray);
}
任何其他建议也将不胜感激。我的第一个 C++ 程序。
最佳答案
问题是
boost::shared_array<const char *> fieldNameArray = ...;
不拥有数组的元素,因此当间接数据消失时,它们将作为悬挂指针保留下来。如果 mysql_fetch_field
返回的指针间接指向合并的数据,这可能发生在 MySQL API 中。
最简单的修复方法是将 fieldNameArray
更改为包含 std::string
。
关于c++ - 数据突然从 Boost shared_array/ptr 中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10977445/
我有一些遗留代码,如下所示: void* getData(DataType dataType) { switch(dataType) { case TYPE_FLOAT:
如何转换 boost::shared_array至 boost::shared_array ? 最佳答案 由于 shared_array 没有 add_ref 方法,您可以按如下方式模拟它: stru
我有一个用例,每次都需要传递 boost::shared_array。如果缓冲区未完全使用,我想创建一个具有相同内存空间但从日期已写入的点开始的新指针 示例代码: boost::shared_ar
在 Visual C++ 中,我尝试动态分配一些 16 字节对齐的内存,以便我可以使用需要内存对齐的 SSE2 函数。现在这是我分配内存的方式: boost::shared_array aData(n
我有一个共享数组:boost::shared_array myarr(new char[m_length]); 我想重新分配数组。我想创建一个具有所需大小的新 shared_array 并使用 swa
如果我有一个 boost::shared_array (或 boost::shared_ptr ),有没有办法获得 boost::shared_ptr哪个与数组共享? 例如,我可能想写: shared
您将如何遍历 boost::shared_array 中的项目?您会对其执行 get() 并使用原始指针作为迭代器吗? 最佳答案 因为你已经在使用 boost,所以可能是这样的: #include
我最近开始使用智能指针。如果我是正确的,则声明智能指针: shared_array a(new double[n]); 但是如果a被封装在一个类中怎么办呢?目前我正在做如下,但这看起来 super 丑
下面的代码在取消注释时会崩溃,而且 get() 中的 shared_array<> 参数似乎有问题。 至少现在 print() 似乎没有崩溃...... 传递 shared_array<> 参数的正确
我正在为某些类编写一些单元测试。这些类使用另一个 comms_client 来执行网络通信。例如,comms_client 提供了一个 send 方法,它接收一个 boost::shared_arra
我有: message->data = boost::shared_array(new char[100]); 里面装满了数据。 我收到了int length 的新char * data(来自旧的C
我有一个提供 GetBuffer() 的流对象和 GetBufferSize()方法。 GetBuffer方法返回原始 uint8_t指针。我想(按值)将此缓冲区传递给另一个需要 shared_arr
在分析我的应用程序后,我发现 malloc 太多了。我很惊讶 shared_ptr 和 shared_array 为引用计数分配了内存。除此之外,封装引用计数的对象包含两个计数 uses_count
boost::shared_array x(new char const *[n]); 在上面的行中(n 是不大于 100 的整数)我正在创建 char const** ( const char**
我在使用 Boost 共享指针时遇到了一些问题。指针指向的数据在不确定的时间突然被删除。在当前程序中(我尝试过许多其他变体)boost::shared_array retArray 的数据案例后在sw
我有一个构造函数接受参数的类 char* name ,然后有一个成员变量是boost::shared_array m_name; 如何复制该参数 char*name至 m_name ? 最佳答案 使用
转换 boost::shared_array 的最佳方法是什么?到 std::string ?以下代码片段有效,但看起来不是很优雅。 boost::shared_array boostString =
虽然存在与 boost::shared_ptr (QSharedPointer) 等价的东西,但我无法找到类似于 boost::shared_array 的东西>. 当然我可以使用类似的东西 QSha
我想在我的应用程序中使用BOOST 智能指针 进行内存管理。但是我不确定我应该为动态分配的数组 shared_ptr 或 shared_array 使用哪个智能指针。 根据 BOOST 文档从 Boo
Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically allocate
我是一名优秀的程序员,十分优秀!