Im trying to find the right way of allocation memory for the following structure.
struct part1 {
char* c1;
char* c2;
}
struct part2 {
int a;
struct part1 *local;
}
struct response {
struct part1* p1;
struct part2* p2;
}
This is what I do, as gathered from the documents.
int myservice ( soap *soap, struct request *request, struct response *resp) {
...
// top level resp is setup by soap_serve
resp->p1 = soap_new_ns__part1(soap,1);
resp->p1->c1 = soap_new_string(soap,10); (also tried soap_malloc(soap,10))
resp->p1->c2 = soap_new_string(soap,10);
strcpy(resp->p1->c1, “first”)
strcpy(resp->p1->c2, “second”)
resp->p2 = soap_new_ns__part2(soap,1);
resp->p2->a = 123;
resp->p2->local = soap_new_ns__part1(soap,1);
resp->p2-> c1 and c1 as above
etc...
But this seems to end in memory leak; although I call the soap_destroy, soap_end.
I am using the process_queue example for the server implementation.
Is there an obvious problem that I am not seeing ?
Thanks.
Related
The conventional way to make an object on the heap is to make a create fn:
const Something = struct {
a:Allocator,
b:[1000]u8,
pub fn create(a:Allocator) !*Something {
var mem = try a.create(Something)
mem.* = {
.a =a,
.b = undefined
};
return mem;
}
}
But what about if I want to put a std lib ArrayHashMap on the heap? For example:
const StringStringArrayHashMap = std.StringArrayHashMap([]const u8);
fn makeMap(a:Allocator) StringStringArrayHashMap {
return StringStringArrayHashMap.init(a);
}
const WithMap = struct {
map:StringStringHashMap
};
fn fillMap(a:Allocator) !WithMap {
var map = makeMap(a);
try map.put("a", "hello");
try map.put("b", "world");
return WithMap { .map = map };
}
fn badMemory(a:Allocator) !void {
const with_map = fillMap(a);
_ = with_map;
}
badMemory will receive a WithMap but it's internal map, having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsade in badMemory.
I can't see any way to make a valid HashMap without somehow hacking the internals of the zig stdlib.
You can put the map on the heap the same way you did with Something type:
var map: *StringStringArrayHashMap = try allocator.create(StringStringArrayHashMap);
map.* = StringStringArrayHashMap.init(allocator);
badMemory will receive a WithMap but it's internal map, having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsafe in badMemory.
This is false. The map is safe to use in badMemory as it's copied to the stack in badMemory. (Or maybe the compiler could decide to pass it as a pointer, I'm not sure if parameter's pass-by-value rule applies to the return value. Doesn't matter here.) But you should probably be careful when copying the map or you might step into the same issue as this question.
I'm attempting to write an external Clang AST modifier that translates anonymous struct and union definitions to a different form. For example, I have:
typedef struct test_case_t {
struct {
int value;
} first[1];
int second;
int third[1];
} test_case_t;
I would like to transform this to:
struct test_case_t {
struct first{
int value;
};
struct first first[1];
int second;
int third[1];
};
typedef struct test_case_t test_case_t;
However, the transform seems to drop the struct first declaration, so this is what I get instead:
struct test_case_t {
struct{ // this should be "struct first"
int value;
};
struct first first[1];
int second;
int third[1];
};
typedef struct test_case_t test_case_t;
How do I go about modifying the struct definition in place and add the first declaration name? I have the RecordDecl of the first variable definition, but I can't seem to figure out how to transform the struct definition.
Ultimately, this is a rather interesting idiosyncrasy of Clang's AST. When representing nested sets of structs and unions, the nested declarations and definitions are split into unique FieldDecls. The struct declaration is lexically parsed first then the variable definition is parsed. This requires that you save off a reference to the struct/union declaration and match it downstream to subsequent variable definitions. This process can be rather tricky, but mimics the following. Specifically, we're looking for struct declarations that match are not isFreeStanding()
for(RecordDecl::decl_iterator iter = RD->decls_begin(), end =
RD->decls_end(); iter != end; ++iter) {
Decl *StructDecl = nullptr;
if(FieldDecl *FD = dyn_cast_or_null<FieldDecl>(*iter)) {
// create new FD
if(const ElaboratedType * NET =
dyn_cast<ElaboratedType>(SemaRef.Context.getBaseElementType(NewFD->getType())))
{
if( StructDecl ){
RecordDecl *MyDecl = dyn_cast<RecordDecl>(StructDecl);
if( MyDecl )
MyDecl->setDeclName(FD->getDeclName());
}
}
}
}else if(TagDecl *TD = dyn_cast<TagDecl>(*iter)){
if(TD->isThisDeclarationADefinition() && !TD->isFreeStanding()){
// save StructDecl
}
}
}
I would like to create a table of data, and keep it in non-dirty memory (so that the table doesn't contribute to them memory usage of the app on iOS and related platforms (tvOS/watchOS)).
The table is an array of two pieces of data: Objective-C class and a numeric value:
#include <Foundation/Foundation.h>
struct TypeMap {
Class class;
int value;
};
I'd like to do something like this:
struct TypeMap map [] = {
{ [NSObject class], 0x1234 }
};
but that obviously doesn't work, clang complains with:
test.m:9:4: error: initializer element is not a compile-time constant
{ [NSObject class], 0x1234 }
^~~~~~~~~~~~~~~~
which makes total sense of course, since [NSObject class] is not a compile-time constant.
But there is a symbol that the dynamic loader is able to resolve: _OBJC_CLASS_$_NSObject, which leads me to something like this:
extern Class OBJC_CLASS_$_NSObject;
struct TypeMap map [] = {
{ OBJC_CLASS_$_NSObject, 0x1234 }
};
The idea being that the dynamic linker can resolve the symbol at runtime, and then mark the memory as read-only (the same way it works for normal code).
Unfortunately it runs into the same problem:
test.m:11:4: error: initializer element is not a compile-time constant
{ OBJC_CLASS_$_NSObject, 0x1234 }
^~~~~~~~~~~~~~~~~~~~~
I'm certain I can express this in assembly code, but I'd like to avoid assembly if possible and stick with Objective-C (no need to implement it once per platform).
Am I completely off track here? Is this even possible?
UPDATE
Working version:
// clang test.m -framework Foundation
#include <Foundation/Foundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
struct TypeMap {
Class class;
int value;
};
extern void* OBJC_CLASS_$_NSObject;
const struct TypeMap map [] = {
{ (Class) &OBJC_CLASS_$_NSObject, 0x1234 },
};
int main ()
{
printf ("%s %p %i\n", class_getName (map[0].class), map [0].class, map [0].value);
return 0;
}
If I understand correctly, a Class in Objective-C is an aggregate type, in the sense in which the C standard uses that term. Then, given
struct TypeMap {
Class class;
int value;
};
extern Class OBJC_CLASS_$_NSObject;
struct TypeMap map [] = {
{ OBJC_CLASS_$_NSObject, 0x1234 }
};
you are asking the dynamic loader to copy the aggregate into your data structure, at load time, which is not a feature that it has.
What you should be able to do instead is have your TypeMap contain pointers to the OBJC_CLASS_$_... symbols:
struct TypeMap {
Class *class;
int value;
};
extern Class OBJC_CLASS_$_NSObject;
const struct TypeMap map[] = {
{ &OBJC_CLASS_$_NSObject, 0x1234 },
// ...
};
Give that a whirl and see how it goes.
(Note the added const on the declaration of map — you need that to get this data structure put in the read-only data segment in the first place.)
Consider this in D programming language:
import luad.all
class C1
{
auto l1 = new LuaState;
l1["somebool"] = true;
this()
~this()
}
class C2
{
C1 cc = new C1;
auto l2 = new LuaState;
// here I want to inject l1["somebool"] to l2
}
void main() { C2 cx = new C2; }
As a solution, it is possible that I make a local variable
bool var = cc.l1["somebool"]
and then insert it in l2 - but this does not seem to be the best solution.
Is there any way to copy one lua stack defined inside a class to another stack in another class?
I don't know much about LuaD or Lua, but you can extract globals into a struct as shown in the last example on this page. And then you can set the values from the struct into l2 state.
// warning: untested
struct State
{
bool somebool;
}
State state;
l1.globals.toStruct!State(state);
foreach (member; __traits(allMembers, State))
{
l2.globals.set(member, __traits(getMember, state, member));
}
I want to pass ByteArray from ActionScript to C function.
basically I want do something like this:
void init() __attribute__((used,annotate("as3sig:public function init(byteData: ByteArray):int"),
annotate("as3package:example")));
void init()
{
//here I want to pass byteArray data to C variable.
//similar to AS3_GetScalarFromVar(cVar, asVar)
}
Unforunately I cannot find any function in flascc docs to help me with this.
Example:
void _init_c(void) __attribute((used,
annotate("as3sig:public function init(byteData:ByteArray) : void"),
annotate("as3import:flash.utils.ByteArray")));
void _init_c()
{
char *byteArray_c;
unsigned int len;
inline_as3("%0 = byteData.bytesAvailable;" : "=r"(len));
byteArray_c = (char *)malloc(len);
inline_as3("CModule.ram.position = %0;" : : "r"(byteArray_c));
inline_as3("byteData.readBytes(CModule.ram);");
// Now byteArray_c points to a copy of the data from byteData.
// Note that byteData.position has changed to the end of the stream.
// ... do stuff ...
free(byteArray_c);
}
The key here is that the heap in C is exposed on the AS3 side as CModule.ram, which is a ByteArray object.
A pointer malloc'd in C is seen in AS3 as an offset into CModule.ram.
You should use CModule.malloc and CModule.writeBytes methods to manipulate with pointers in C-style manner. Take a look on $FLASCC/samples/06_SWIG/PassingData/PassData.as
void _init_c(void) __attribute((used,
annotate("as3sig:public function init(byteData:ByteArray) : void"),
annotate("as3import:flash.utils.ByteArray")));
void _init_c()
{
char *byteArray_c;
unsigned int len;
inline_as3("%0 = byteData.bytesAvailable;" : "=r"(len));
byteArray_c = (char *) malloc(len);
inline_as3("byteData.readBytes(CModule.ram, %0, %1);" : : "r"(byteArray_c), "r"(len));
// Now byteArray_c points to a copy of the data from byteData.
// Note that byteData.position has changed to the end of the stream.
// ... do stuff ...
free(byteArray_c);
}