g++ Static analysis: false positive with -fanalyzer? - g++

Running this very little snippet, to show a problem I have with a much larger code:
// Type your code here, or load an example.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
int main() {
auto res = make_unique<int>();
auto ptr = res.get();
if (ptr) {
*ptr = 5;
cout << *ptr << endl;
}
return 0;
}
with the -fanalyzer switch, I get a warning
warning: dereference of possibly-NULL 'operator new(4)' [CWE-690] [-Wanalyzer-possible-null-dereference]
But clearly I made all I could do to avoid this warning, but it is buried in the STL, which returns a unique_ptr with no validity control..
I understand the word "possibly" though..
Anyway to correct this on my side?
Update:
I made a mistake in the first go, now corrected
Update 2:
Even that code is refused
// Type your code here, or load an example.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
int main() {
auto i = new int(3);
if (!i) {
return 1;
}
unique_ptr<int> res(i);
auto ptr = res.get();
if (!ptr) {
return 1;
}
*ptr = 5;
cout << *ptr << endl;
return 0;
}
Please, see here

As for now (gcc-12), the analyzer is not recommended for C++ code although work is underway to support it.
https://developers.redhat.com/articles/2022/04/12/state-static-analysis-gcc-12-compiler#toward_support_for_c__

Related

How to copy a surface mesh in CGAL

I want to copy a mesh with the function copy_face_graph(source, target). But the target mesh is different (it has same number of vertices and faces, but the coordinates and the order are totally different).
The code:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <iostream>
#include <fstream>
#include <CGAL/boost/graph/copy_face_graph.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> Mesh;
namespace PMP = CGAL::Polygon_mesh_processing;
int main(int argc, char* argv[]) {
const char* filename1 = (argc > 1) ? argv[1] : "data/blobby.off";
std::cout << ".off loaded" << std::endl;
std::ifstream input(filename1);
Mesh mesh_orig;
if (!input || !(input >> mesh_orig))
{
std::cerr << "First mesh is not a valid off file." << std::endl;
return 1;
}
input.close();
// ========================================================
Mesh mesh_copy;
CGAL::copy_face_graph(mesh_orig, mesh_copy);
// ========================================================
std::ofstream mesh_cpy("CPY_ANYLYZE/mesh_copy.off");
mesh_cpy << mesh_copy;
mesh_cpy.close();
return 0;
}
Dose anyone knows how to get a complete same mesh from the original mesh? Do I need add the named parameters, or maybe using another function?
Thanks a lot
Except if you intend to write some code working with different data structures, you can use the copy constructor from the Surface_mesh class, Mesh mesh_copy(mesh_orig). copy_face_graph does not do a raw copy because it works also if the input and output are of different types. However the output should be the same up to the order of the simplices.

How to set different decimal places in same rapidjson document

I have made a rapidjson document with all my objects and values using usual AddMember() method. Now I want to get the string out of that document for publishing to a mqtt broker. But inside that string, some members shall have 2 decimal places, some only one, and others all decimals.
I don't find how to set decimal place for a specific member after the document was fully builded.
I succeeded to do so by building my json document with a writer but this is not what i want to do because this document can't be easily modified:
#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h> // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
Document doc;
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
writer.StartObject();
writer.Key("member1");
writer.SetMaxDecimalPlaces(2);
writer.Double(1.0000001);
writer.Key("member2");
writer.SetMaxDecimalPlaces(3);
writer.Double(3.123456);
writer.Key("member3");
writer.SetMaxDecimalPlaces(8);
writer.Double(2.123456);
writer.EndObject();
cout << buffer.GetString() << endl;
return 0;
}
./decimal
{"member1":1.0,"member2":3.123,"member3":2.123456}
Now, this how i build my document:
#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h> // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
Document doc;
Document::AllocatorType& allocator = doc.GetAllocator();
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
doc.SetObject();
doc.AddMember("member1", 1.0000001, allocator);
doc.AddMember("member3", 3.123456, allocator);
doc.AddMember("member2", 2.123456, allocator);
writer.SetMaxDecimalPlaces(2);
doc.Accept(writer);
cout << buffer.GetString() << endl;
return 0;
}
./decimal
{"member1":1.0,"member2":2.12,"member3":3.12}
The SetMaxDecimalPlaces() applies to the whole document this way
I would like to get same output has first code example but using document made from second source code. How can i tell the writer to format each member differently ?
I'm super late to the party, but you can create a second writer with different writing settings:
StringBuffer buffer;
Writer<StringBuffer> writer1(buffer); // original writer
Writer<StringBuffer> writer2(buffer); // a new second writer
writer1.SetMaxDecimalPlaces(1);
writer2.SetMaxDecimalPlaces(2);
and then use the specific writers to write directly into the buffer instead of using the doc to call the writer:
writer.Key("member1");
writer.Double(1.0);
writer2.Key("member2");
writer2.Double(2.12);
writer2.Key("member3");
writer2.Double(3.12);
Full example:
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
StringBuffer buffer;
Writer<StringBuffer> writer1(buffer);
Writer<StringBuffer> writer2(buffer);
writer1.SetMaxDecimalPlaces(2);
writer2.SetMaxDecimalPlaces(2);
writer1.StartObject();
writer1.Key("member1");
writer1.Double(1.0);
writer2.Key("member2");
writer2.Double(2.12);
writer2.Key("member3");
writer2.Double(3.12);
writer1.EndObject();
cout << buffer.GetString() << endl;
return 0;
}

GetProcAddress returning the correct address with Visual C++ and an incorrect address with g++

This is going to sound really strange. I am using Visual Studio 2017 C++ (native mode) and also, g++ 4.7.1-2 of the MingW toolchain. Target is Windows 64bit.
Using VS C++, I compile the following trivial program:
`
#include "stdafx.h"
#include <Windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);
RTLINT64 RtlInt64 = (RTLINT64) nullptr;
int main()
{
UNICODE_STRING unicodestring = { 0 };
WCHAR localbuffer[256] = { 0 }; // way more than enough
__int64 value = 0;
unicodestring.Length = 0;
unicodestring.MaximumLength = sizeof(localbuffer);
unicodestring.Buffer = (PWCH) &localbuffer;
// get ntdll's module handle
HMODULE NtDllModule = LoadLibrary(L"ntdll.dll");
if (NtDllModule)
{
RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
"RtlInt64ToUnicodeString");
value = 0xFFFFFFFFF;
RtlInt64 (value, 10, &unicodestring);
wprintf(L"%s\n", unicodestring.Buffer);
}
return 0;
}
`
As expected, GetProcAddress returns the address of RtlInt64ToUnicodeString (no surprise there!)
The code below is, with exception of the includes, pretty much a carbon copy of the above. Yet, somehow, in that version compiled with G++, GetProcAddress returns the address of RtlInterlockedSetBitRun instead of the address of RtlInt64ToUnicodeString (that IS a surprise!). Here is the code:
// GCC and MingW version
#include <Windows.h>
#include <winbase.h>
#include <strsafe.h>
#include <winuser.h>
#include <winternl.h>
// --------------------------------------------------------------------------
typedef NTSTATUS(NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);
RTLINT64 RtlInt64 = (RTLINT64) nullptr;
// --------------------------------------------------------------------------
int main(int argc, char *argv[])
{
WCHAR localbuffer[256] = {0}; // way more than enough
UNICODE_STRING unicodestring = {0};
__int64 value = 0;
unicodestring.Length = 0;
unicodestring.MaximumLength = sizeof(localbuffer);
unicodestring.Buffer = (PWCH) &localbuffer;
// get ntdll's module handle
HMODULE NtDllModule = LoadLibraryW(L"ntdll.dll");
if (NtDllModule)
{
RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
"RtlInt64ToUnicodeString");
// the above call to GetProcAddress returned the address of
// RtlInterlockedSetBitRun instead of the address of the requested function
// as a result, the statements below don't work.
value = 0xFFFFFFFFF;
RtlInt64(value, 10, &unicodestring);
wprintf(L"%s\n", unicodestring.Buffer);
}
return 0;
}
my question is: is there something in the above code that justifies the discrepancy ?
Also note that, I am using G++ with a tool called VisualGDB which integrates the compiler and the debugger into Visual Studio. Normally things of that kind can cause strange "side effects" but, in this case, it seems rather unlikely for something that has nothing to do with ntdll to be the culprit.
Thank you for your help.

How to convert a serialized tensorflow::Example into an input to a session

I've used the following tutorial to export a saved model created by an estimator:
https://github.com/MtDersvan/tf_playground/blob/master/wide_and_deep_tutorial/wide_and_deep_basic_serving.md
I'm trying to load this model in c++. I've managed to create a serialized tensorflow::Example using c++. How do I convert this into a single Tensor?
The tutorial uses tf.contrib.util.make_tensor_proto(serialized, shape=[1])). What is the equivalent C++ API?
It's complicated a little than write in python, here's code example may helps:
#include <gtest/gtest.h>
#include <grpc/grpc.h>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/security/credentials.h>
#include <grpc++/security/credentials.h>
#include <iostream>
#include "tensorflow/core/framework/tensor.pb.h"
#include "tensorflow/core/example/example.pb.h"
#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow_serving/apis/prediction_service.grpc.pb.h"
#include "tensorflow_serving/apis/prediction_service.pb.h"
using namespace std;
namespace tensorflow {
namespace serving {
TEST(GRPCCppClient, TestPredict) {
shared_ptr<grpc::Channel> channel = grpc::CreateChannel("127.0.0.1:30355", grpc::InsecureChannelCredentials());
shared_ptr<PredictionService::Stub> stub_ = PredictionService::NewStub(channel);
tensorflow::TensorProto tensorProto;
tensorflow::TensorShapeProto tensorShapeProto;
PredictRequest predictRequest;
PredictResponse predictResponse;
tensorflow::TensorShapeProto_Dim* dim_0 = tensorShapeProto.add_dim();
dim_0->set_size(1);
tensorProto.mutable_tensor_shape()->CopyFrom(tensorShapeProto);
Example example;
/*Construct example..*/
std::string test_str;
example.SerializeToString(&test_str);
tensorProto.set_dtype(DT_STRING);
tensorProto.add_string_val(test_str);
(*predictRequest.mutable_inputs())["inputs"] = tensorProto;
predictRequest.mutable_model_spec()->set_name("default"); /*set your own model name*/
grpc::ClientContext context;
grpc::Status status = stub_->Predict(&context, predictRequest, &predictResponse);
if (!status.ok()) {
std::cout << "GetFeature rpc failed." << std::endl;
ASSERT_TRUE(false);
}
cout<<"------------\n"<<predictResponse.DebugString()<<endl;
}
}
}

Converting Surface_mesh to Nef_polyhedron_3

I'm trying to use CGAL to do some boolean operations on meshes.
How do I convert from Surface_mesh to Nef_polyhedron_3?
EDIT:
I've tried with this code, but I don't know how to continue...
#include <iostream>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
using namespace std;
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
int main()
{
Mesh m;
auto a = m.add_vertex(K::Point_3(0,0,0));
auto b = m.add_vertex(K::Point_3(0,0,0));
auto c = m.add_vertex(K::Point_3(0,0,0));
m.add_face(a,b,c);
Mesh::Halfedge_range range = m.halfedges();
for(Mesh::Halfedge_index hei : range)
{
// ??? <<--
std::cout << hei << std::endl;
}
return 0;
}
Thanks
I think the suggested way to do this is to use the 3d polyhedral surface package instead. The Nef 3 documentation describes the conversion between Polyhedron_3 and Nef_3. The only difference between the 3d polyhedral surface package and the surface mesh package is that, it is pointer based rather than index based.