Does Malloc allocate the correct space? - malloc

I have a structure which is passed to a function. There some values should be changed. Back in the main I should read out the new values of my structure.
In a sample project it works EASILY!
In my main code in Visual Studio Code with ARM Cortex M3 and a crazy library it DOESNT WORK
(update: something must be wrong with compiler: I checked it hard and observed that not all variables are changed!!! )
My first big goal is to change chip_count within my structure.
Here the program flow:
I create a pointer to a special type of structure.
I pass this pointers address to a function.
The function creates a new adress with malloc.
The passed pointer gets this new address.
So it points now on the malloc.
Some variable are of the malloc structure are changed.
Return to main
Access the malloc space and read out the changed stuff
Result:
YES IT WORKS
Sry I added some more functions to understand const declarations better.
Pointer stuff:
vtss_state_t is the same as struct vtss_state_s
vtss_inst_t in turn is a pointer on struct vtss_state_s or vtss_state_t
the function vtss_create() has a parameter *vtss_inst_t const inst
This is a pointer on the pointer of of vtss_sate_s or a pointer to vtss_inst_t.
In the function at the end the adress of malloc is passed to (*inst).
(*inst) is the content of the of the pointer on which inst is pointing to.
So the pointer will point to malloc().
I hope this is right...
FIRST APPROACH ONLINE COMPILER
I just wanted to see if I can change values in my passed structure.
Result: YES
FILE:state.h
#include <stdint.h>
/******************************************************************************
Structures
*******************************************************************************/
typedef struct tests
{
int x;
} tests_t;
typedef uint32_t u32;
// This is the structure with chip_count
typedef struct vtss_state_s
{
int a;
int cookie;
tests_t u;
int port_count;
u32 chip_count // doesnt change in my real program :(
} vtss_state_t;
// typedef this structure so vtss_inst_t points to it...(?)
typedef struct vtss_state_s *vtss_inst_t;
FILE: main.c
/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "state.h"
#define VTSS_PORT_COUNT 1
#define VTSS_PORTS VTSS_PORT_COUNT
//
// some global structure
vtss_inst_t testspace;
vtss_inst_t *testspace_ptr;
/******************************************************************************
functions
*******************************************************************************/
// vtss_inst_get ()
// const adress another access style
void
vtss_inst_get (const vtss_inst_t inst)
{
printf ("\ninst get()");
printf ("\ninst get() adress of inst:%d", inst);
inst->a = 1111;
}
// This function just should proof that it can change the content
void
vtss_inst_default_set (vtss_state_t * vtss_state)
{
vtss_state->port_count = VTSS_PORTS; // 1
}
//** This is the function which should change "chip_count"
// Man soll einen Pointer auf einen Pointer auf die Struktur C<bergeben (wo sich chip_count befindet )
void
vtss_inst_create (vtss_inst_t * const inst)
{
printf ("\r\n**vtss_inst_create()");
vtss_state_t *vtss_state; // temporary pointer ( just points to a structure )
vtss_state_t *vtss_state_2; // just a test compare
// pass temporary pointer a new memory space:
vtss_state = malloc (sizeof (*vtss_state)); // is this correct? anyway it also doesnt work without this malloc style
printf ("\r\n\t malloc=: %d", vtss_state);
// pass test temporary pointer a new memory space:
vtss_state_2 = malloc (sizeof (*vtss_state_2));
printf ("\r\n\t (test) malloc2: %d", vtss_state_2);
//Test: pass the temporary pointer even deeper & change content of structure where it points to
// (change variable port_count to 1)
vtss_inst_default_set (vtss_state);
vtss_inst_default_set (vtss_state_2);
//Test:Change values of the structure:
vtss_state->a = 1;
vtss_state->chip_count = 12121;
vtss_state_2->chip_count = 12121;
// ** Giving back the new adress from malloc:
// Test:(from vtss_state or vtss_state2)
(*inst) = vtss_state; //passing adress1
//Test: a should have the correct value:
printf ("\r\n\ta=1? a =%d ", (*inst)->a);
(*inst) = vtss_state_2; //passing adress2
// Some extra tests:
(testspace) = vtss_state_2; // extra Test: pass the adress to a test pointer
testspace_ptr = &testspace; // extra Test: pass the adress to a test pointer
(*testspace_ptr) = vtss_state_2; // extra Test: pass the adress to a test pointer
vtss_state_2->a = 22; // extra Test: change content of test pointer
printf ("\r\n\ta=22? a=%d ", (*inst)->a); //
}
/******************************************************************************
main
*******************************************************************************/
int
main ()
{
// **The main structure:
vtss_state_t state_test;
state_test.a = 1234; // pass some test value
// **pointer to type of vtss_state_t
vtss_inst_t inst;
// **pass the adress of the structure!:
inst = &state_test;
// Test: add a value to a structure of the structure:
// (is the same like inst->)
state_test.u.x = 123;
// Test:
inst->chip_count = 888;
vtss_inst_get (inst);
// Test: I declared two global structure to test global access:
printf ("\ntestspace points to: %d", testspace);
printf ("\ntestspace ptr points to: %d", testspace_ptr);
// Test variable a:
printf ("\n1234? inst->a=%d", inst->a);
// Test: show value of structure in a strucure:
printf ("\n123? state_test.u.x=%d", state_test.u.x);
// Test: before & after address is changed:
printf ("\r\n * Before create(): Adress inst:%d", inst);
printf ("\r\n******* Before create():chip_count: %d", inst->chip_count);
vtss_inst_create (&inst);
printf ("\r\n\n * After create(): Adress of inst:%d", inst);
printf ("\r\n\t 22? a:%d", inst->a);
printf
("\r\n even the layer2 function in create() worked:\n port_count=1?: %d",
inst->port_count);
printf
("\r\n\n\n******* chip_count has changes correctly to 12121: %d\n\n\n",
inst->chip_count);
//extra tests with the global structures:
printf ("\ntestspace points to: %d", testspace);
printf ("\n testspace has the correct value a: %d", testspace->a);
printf ("\n testspace_ptr has the correct value a:: %d",
(*testspace_ptr)->a);
printf ("\n adress of pointer testspace_ptr points to?:%d", testspace_ptr);
// extra test:
vtss_inst_get (inst);
printf ("\n there is even access to a:%d", inst->a);
printf ("\nPE-Hello World");
return 0;
}
SECOND APPROACH: ARM CORTEX M3 in VSC:
I just want to change chip_count but the library function doesn't do it!
vtss_rc **vtss_inst_create**(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 777;
(*inst) = vtss_state;
I call it in the main: vtss_inst_create(&create, &inst);
( now I also deleted the third test parameter: I should change it here, but result is anyway same)
when I read chip_count out in the main :
sprintf(t2, "\r\n main: chipcount should be 777 %d ??", (int)(inst->chip_count));
print_uart(t2);
Then it prints:
482531848 !!!!!!
I copied this function:
void createtest2(vtss_inst_t *const inst)
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 888;
(*inst) = vtss_state;
}
it is called: createtest2(&inst);
sprintf(t2, "\r\n main: wie in create() chipcount 888?: %d", (int)(inst->chip_count));
print_uart(t2);
it prints 888 correctly i guess because it prints it ..
I copied it also with correct header:
vtss_rc vtss_inst_create3(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 222;
(*inst) = vtss_state;
(void)create;
(void)print;
return 1;
}
I call it: vtss_inst_create3(&create, &inst, spitest);
(ignore please the third parameter)
it prints out 222 correctly
How is that possible?
Or is this simply magic :)
Update: I checked it and it is shocking to me.
lol
it works in every kind of function but not with that one I want to do it xD
First I just copied the function but only one parameter. It worked.
Then I copied it with all parameters. It worked.
But the original library func. doesn't work.
In the past I changed the library function a little bit:
Ok in the past a tuned the library function by adding one little parameter as a little test.
In combination, that it is a library function in not located in the same file it may cause some trouble.
I will now change the header back to normal:
Normal:
vtss_rc vtss_inst_create(const vtss_inst_create_t *const create,
vtss_inst_t *const inst)
How i tuned it:
vtss_rc vtss_inst_create(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
update: lol I rechanged the function it back to normal.
Hmmm....
Another file?
Then it must be because the function is in another file or what.
I checked inside the functions they point to the same addresses as outside (main).. I mean the value of inst.
Todo I print out now the addresses of chip_count
Update: OMG something is wrong with the compiler. I compared it as described with similar functions.
Same function different result of chip_count.
But another variabale e.g. "cookie" can be changed!
So one variable is change another not.
This was really confusing to me because I didn't expect it!
CMAKE:
Maybe there is an error which is suppressed by my CMAKE. So the compiler ignores the error. At runtime the error comes to light.
add_target_compile_flags(base PRIVATE "" "-Wno-unused-parameter" "-Wno-pedantic" "-Wno-format" "-Wno-sign-conversion" "-Wno-switch-default" "-Wno-conversion" "-Wno-unused-variable" "-Wno-undef" "-Wno-unused-but-set-variable" "-Wno-unused-function" "-Wno-implicit-function-declaration" "-Wno-uninitialized")

Related

include_str for null terminated string

I need to read a file into a null terminated string at compile time.
Working in Rust OpenGL. I have a shader source code stored in a separate file. The function that will eventually read the source is gl::ShaderSource from the gl crate. All it needs is a pointer to a null terminated string (the std::ffi::CStr type).
Typically the guides I have seen read the shader source file using include_str!, then at run time allocate a whole new buffer of length +1, then copy the original source into the new buffer and put the terminating 0 at the end. I'd like to avoid all that redundant allocating and copying and just have the correctly null terminated string at compile time.
I realize it is somewhat petty to want to avoid an extra allocation for a short shader file, but the principle could apply to many other types of larger constants.
While scrolling through suggested questions during the preview I saw this: How do I expose a compile time generated static C string through FFI?
which led me to this solution:
let bytes1 = concat!(include_str!("triangle.vertex_shader"), "\0");
let bytes2 = bytes1.as_bytes();
let bytes3 = unsafe {
CStr::from_bytes_with_nul_unchecked(bytes2)
};
println!("{:?}", bytes3);
Does this accomplish avoiding the runtime allocation and copying?
Your code is unsound. It fails to verify there are no interior NUL bytes.
You can use the following function to validate the string (at compile time, with no runtime cost):
pub const fn to_cstr(s: &str) -> &CStr {
let bytes = s.as_bytes();
let mut i = 0;
while i < (bytes.len() - 1) {
assert!(bytes[i] != b'\0', "interior byte cannot be NUL");
i += 1;
}
assert!(bytes[bytes.len() - 1] == b'\0', "last byte must be NUL");
// SAFETY: We verified there are no interior NULs and that the string ends with NUL.
unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }
}
Wrap it in a little nice macro:
macro_rules! include_cstr {
( $path:literal $(,)? ) => {{
// Use a constant to force the verification to run at compile time.
const VALUE: &'static ::core::ffi::CStr = $crate::to_cstr(concat!(include_str!($path), "\0"));
VALUE
}};
}
Then use it:
let bytes = include_cstr!("triangle.vertex_shader");
If there are interior NUL bytes the code will fail to compile.
When CStr::from_bytes_with_nul() becomes const-stable, you will be able to replace to_cstr() with it.
Yes that should work as intended. If you want you can even bundle it into a simple macro.
macro_rules! include_cstr {
($file:expr) => {{
// Create as explicit constant to force from_bytes_with_nul_unchecked to
// perform compile time saftey checks.
const CSTR: &'static ::std::ffi::CStr = unsafe {
let input = concat!($file, "\0");
::std::ffi::CStr::from_bytes_with_nul_unchecked(input.as_bytes())
};
CSTR
}};
}
const VERTEX_SHADER: &'static CStr = include_cstr!("shaders/vert.glsl");
const FRAGMENT_SHADER: &'static CStr = include_cstr!("shaders/frag.glsl");

How to write #define expressions with nested brackets in cython?

C expression:
#define EFX_REVERB_PRESET_GENERIC \
{ 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
I want to define this expression in the .pxd file.
I have to pass this expression as parameters to some C functions. So I don't use it for Python.
Source: OpenAL-Soft: https://github.com/kcat/openal-soft/blob/master/include/AL/efx-presets.h#L37
It's worth realising that not everything has a direct translation from C to Cython. In this case EFX_REVERB_PRESET_GENERIC can't really be defined using a type because it isn't a type - it's just a collection of brackets and numbers. These brackets and numbers are only valid in a small number of places:
void other_func(WhateverTheStructIsCalled s);
void func() {
WhateverTheStructIsCalled s = EFX_REVERB_PRESET_GENERIC; // OK
s = EFX_REVERB_PRESET_GENERIC; // wrong - not an initialization
other_func(EFX_REVERB_PRESET_GENERIC); // also doesn't work
}
Therefore it doesn't really fit into Cython's model so you can't wrap it directly.
What I'd do is write a small C wrapper yourself. You can do this with Cython's "inline C code" function:
cdef extern from *:
"""
WhateverTheStructIsCalled get_EFX_REVERB_PRESET_GENERIC(void) {
WhateverTheStructIsCalled s = EFX_REVERB_PRESET_GENERIC;
return s;
}
"""
WhateverTheStructIsCalled get_EFX_REVERB_PRESET_GENERIC()
Then use get_EFX_REVERB_PRESET_GENERIC() to call this function and get the relevant initialized structure.

segfault on Rcpp function when running with sanitizers (from rhub)

I am writing a package using Rcpp Function, the package compiles, and R CMD Check also works fine. Earlier, the input to package's cvode function was an XPtr, but now the input can be both XPtr or an R or Rcpp function (the implementation was based on a earlier post). Currently, input functions in R, Rcpp and Rcpp::XPtr work in the package.
The package had previously had clang-UBSAN issues, so I am trying to detect them beforehand now using rhub package. On running check_with_sanitizers() command from the rhub package, I am getting the following error:
eval.c:677:21: runtime error: member access within null pointer of type 'struct SEXPREC'
─ *** caught segfault ***
address (nil), cause 'memory not mapped'
Segmentation fault (core dumped)
I have been able to isolate the error to the line ydot1 = rhs_fun(t, y1); in the following piece of code, i.e., commenting/un-commenting the expression above reproduces the error.
My question is - is there a check I should be performing before calling the rhs_fun Function, to avoid the segmentation fault error?
Note - check_with_valgrind() produces no error.
Thanks!
// struct to use if R or Rcpp function is input as RHS function
struct rhs_func{
Function rhs_eqn;
};
int rhs_func(realtype t, N_Vector y, N_Vector ydot, void* user_data){
// convert y to NumericVector y1
int y_len = NV_LENGTH_S(y);
NumericVector y1(y_len); // filled with zeros
realtype *y_ptr = N_VGetArrayPointer(y);
for (int i = 0; i < y_len; i++){
y1[i] = y_ptr[i];
}
// convert ydot to NumericVector ydot1
// int ydot_len = NV_LENGTH_S(ydot);
NumericVector ydot1(y_len); // filled with zeros
// // cast void pointer to pointer to struct and assign rhs to a Function
struct rhs_func *my_rhs_fun = (struct rhs_func*)user_data;
if(my_rhs_fun){
Function rhs_fun = (*my_rhs_fun).rhs_eqn;
// use the function to calculate value of RHS ----
// Uncommenting the line below gives runtime error
// ydot1 = rhs_fun(t, y1);
}
else {
stop("Something went wrong, stopping!");
}
// convert NumericVector ydot1 to N_Vector ydot
realtype *ydot_ptr = N_VGetArrayPointer(ydot);
for (int i = 0; i< y_len; i++){
ydot_ptr[i] = ydot1[i];
}
// everything went smoothly
return(0);
}
An update - based on the comments below, I have added checks. So the check succeeds, but I can see the rhs_fun is NULL as the code goes to the stop message.
if(my_rhs_fun){
Function rhs_fun = (*my_rhs_fun).rhs_eqn;
// use the function to calculate value of RHS ----
if (rhs_fun){
ydot1 = rhs_fun(t, y1);
}
else{
stop("Something went wrong");
}
}
else {
stop("Something went wrong, stopping!");
}
An added check is added to the struct also
if (Rf_isNull(input_function)){
stop("Something is wrong with input function, stopping!");
}
The checks succeed, but I see that rhs_fun is NULL as the else message is printed
Error in cvode(time_vec, IC, ODE_R, reltol, abstol) :
Something went wrong
Execution halted
Not sure why, as the examples I have tried have worked without complaints.
The most likely candidate for a NULL reference is rhs_fun. So it makes sense to test that before executing the function:
if(rhs_fun) {
...
} else {
stop(...)
}
The R API function Rf_isNull would not be appropriate here, since that checks for an SEXP of type NILSXP and segfaults for an actual nullptr.
In addition I would check that you are not inserting a NULL reference into the struct, though I find it unlikely that anything is going wrong there.
Overall this is just a workaround. It would be interesting to know what triggers this behavior.

node-ffi - Passing string pointer to C library

I have API in C library as bellow
EXPORT void test(char *a) {
// Do something to change value of "a"
}
And I want to passing a pointer of string to that API with node-ffi and ref. I was tried many ways but unsuccessful. Someone else can help me resolve it?
How are you going to prevent a buffer overflow? Most functions which output a string also take a parameter to specify the max length that has been allocated for that string. This issue not withstanding, the following worked for me:
//use ffi and ref to interface with a c style dll
var ffi = require('ffi');
var ref = require('ref');
//load the dll. The dll is located in the current folder and named customlib.dll
var customlibProp = ffi.Library('customlib', {
'myfunction': [ 'void', [ 'char *' ] ]
});
var maxStringLength = 200;
var theStringBuffer = new Buffer(maxStringLength);
theStringBuffer.fill(0); //if you want to initially clear the buffer
theStringBuffer.write("Intitial value", 0, "utf-8"); //if you want to give it an initial value
//call the function
customlibProp.myfunction(theStringBuffer);
//retrieve and convert the result back to a javascript string
var theString = theStringBuffer.toString('utf-8');
var terminatingNullPos = theString.indexOf('\u0000');
if (terminatingNullPos >= 0) {theString = theString.substr(0, terminatingNullPos);}
console.log("The string: ",theString);
I'm also not positive that your c function has the right declaration. The function I was interfacing with had a signature that was like:
void (__stdcall *myfunction)(char *outputString);
Maybe EXPORT will resolve to the same thing, I just haven't done any c programming recently enough to remember.

Convert wstring to WS_STRING

What is the best way to convert wstring to WS_STRING?
Trying with macros:
wstring d=L"ddd";
WS_STRING url = WS_STRING_VALUE(d.c_str()) ;
And have error:
cannot convert from 'const wchar_t *' to 'WCHAR *'
Short answer:
WS_STRING url = {};
url.length = d.length();
WsAlloc(heap, sizeof(WCHAR) * url.length, (void**)&url.chars, error);
memcpy(url.chars, d.c_str(), sizeof(WCHAR) * url.length); // Don't want a null terminator
Long answer:
Don't use WS_STRING_VALUE on anything other than a WCHAR[]. You can get it to compile using const_cast<> but you will run into two issues:
The WS_STRING will have an incorrect length member due to the macro's use of RTL_NUMBER_OF instead of looking for null termination.
The WS_STRING will just reference d - it will not take a copy. This is obviously problematic if it's a local variable.
The relevant code snippets:
// Utilities structure
//
// An array of unicode characters and a length.
//
struct _WS_STRING {
ULONG length;
_Field_size_(length) WCHAR* chars;
};
// Utilities macro
//
// A macro to initialize a WS_STRING structure given a constant string.
//
#define WS_STRING_VALUE(S) { WsCountOf(S) - 1, S }
// Utilities macro
//
// Returns the number of elements of an array.
//
#define WsCountOf(arrayValue) RTL_NUMBER_OF(arrayValue)

Resources