The folowing code is giving a segfault when reaching the insert statement:
rna* annealer::anneal(rna strand1, rna strand2, const rna & opponent){
std::vector<nukleotid*>::iterator sit2;
std::vector<nukleotid*>::iterator eit2;
std::vector<nukleotid*>::iterator eit;
if(tryAnneal(strand1, strand2, opponent)) {
eit = strand1.getStrand().end();
sit2 = strand2.getStrand().begin();
eit2 = strand2.getStrand().end();
//here be segfault
strand1.getStrand().insert(eit, sit2, eit2);
strand1.isAnnealed = true;
rna* str = &strand1;
std::cout << *str << std::endl;
return str;
}
//...
return NULL;
}
rna contains a vector, which is returned by getStrand().
Its driving me crazy. I really cant understand why theres a segfault. A slightly different version of the code, in which in didnt declare new iterators, but was just passing strand1.getStrand().end(); (and the two other), to vector::insert() derictly threw a length_error which does not make any sense either, as my vectors are small (~10 elements).
can anyone see what am i doing wrong here?`
If getStrand() returns a vector by value, then sit2 and eit2 are iterators into different copies of the vector, and both copies are destroyed as soon as you obtain the iterators. You need either to return the vector by reference or save the copy of the vector and obtain iterators from that one copy instead.
My guess is that getStrand is returning a copy of the vector, instead of a reference to it. That will cause the iterators you're using (eit, sit2, and so on) to become invalid immediately after they're created!
Can you paste your declaration for that method?
Related
Its a simple code, saving car type objects into a car type array. I am trying to use pointer here to pass array reference.
There are 2 problems:
1 - I can't initialize it as empty array. When I use make, it says:
cannot make type *[]car
2 - If I don't use make, runtime error occurs:
panic: runtime error: invalid memory address or nil pointer dereference
Code:
import "fmt"
type car struct {
plate string
color string
}
func main() {
var _cars *[]car // list of cars
_cars = make(*[]car, 4) // initialize empty cars list
saveCar(_cars, car{"ABC-123", "Black"})
saveCar(_cars, car{"ABC-456", "Black"})
saveCar(_cars, car{"ABC-789", "Black"})
fmt.Println(_cars)
}
func saveCar(_cars_list *[]car, _car car) int {
for index, current := range *_cars_list {
// if empty place found, save car
if (car{}) == current {
// save car
(*_cars_list)[index] = _car
// return the saved index
return index
}
}
return -1
}
Changing this would make your code work:
tCars := make([]car, 4)
_cars = &tCars
1 - cannot make type *[]car
You observe it because make creates slice, map or chan. In the example you gave you tried to create pointer to a slice which is none of the typed make works with.
2 - If I don't use make, runtime error occurs:
that's another problem - you have type "pointer to a slice of car", not "a slice of car". And in general you need to initialize pointer types before using.
Overall there is no need to use pointer to a slice rather than plain slice in your case, because you don't use append, to there is no chance for reallocation of backed storage.
However, in a real world scenario, when you don't know amount of car instances you are going to add, is much better to use append instead of iterating through slice till the last non-initialized value.
summary:
to make your program work change *[]car to []car everywhere (example https://play.golang.org/p/lpCtvXqG6UY)
another (and probably better) way is to use append instead of saveCar (don't forget to use returned value in case of happened re-allocation, example: https://play.golang.org/p/L8V10tSb-IJ)
first timer here,
The first NOTE in SliceTricks suggests that there is a potential memory leak problem when cutting or deleting elements in a slice of pointers.
Is the same true for a map? For example: https://play.golang.org/p/67cN0JggWY
Should we nil the entry before deleting from map? Like so:
m["foo"] = nil
What if we simply clear the map?
m = make(map[string]*myStruct)
Will the garbage collector still pick it up?
Thanks in advance
Checking the sources
Although this is not documented anywhere, checking the sources: runtime/hashmap.go, mapdelete() function:
558 func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
// ...
600 memclr(k, uintptr(t.keysize))
601 v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
602 memclr(v, uintptr(t.valuesize))
// ...
618 }
As you can see, storage for both the key (line #600) and the value (line #602) are cleared / zeroed.
This means if any of the key or value was a pointer, or if they were values of complex types containing pointers, they are zeroed and therefore the pointed objects are no longer referenced by the internal data structures of the map, so there is no memory leak here.
When there is no more reference to a complete map value, then the complete memory area of the map will be garbage collected, and all the pointers included in keys and values are also not held anymore by the map; and if no one else has reference to the pointed objects, they will be garbage collected properly.
Constructing an example to prove this
We can also construct a test code which proves this without examining the sources:
type point struct {
X, Y int
}
var m = map[int]*point{}
func main() {
fillMap()
delete(m, 1)
runtime.GC()
time.Sleep(time.Second)
fmt.Println(m)
}
func fillMap() {
p := &point{1, 2}
runtime.SetFinalizer(p, func(p *point) {
fmt.Printf("Finalized: %p %+v\n", p, p)
})
m[1] = p
fmt.Printf("Put in map: %p %+v\n", p, p)
}
Output (try it on the Go Playground):
Put in map: 0x1040a128 &{X:1 Y:2}
Finalized: 0x1040a128 &{X:1 Y:2}
map[]
What does this do? It creates a *Point value (pointer to a struct), puts it in the map, and registers a function that should be called when this pointer becomes unreachable (using runtime.SetFinalizer()), and then deletes the entry containing this pointer. Then we call runtime.GC() to "force" an immediate garbage collection. I also print the map at the end just to make sure the whole map is not garbage collected due to some optimization.
The result? We see the registered function gets called, which proves the pointer was removed from the map as the result of the delete() call, because (since we had no other references to it) it was eligible for garbage collection.
No, there will not be any memory leaks when deleting from a map.
In case of slices, since a slice actually uses an underlying array, as long as the slice exists - even if it uses just one slot in that array - the pointer items inside the array can not get garbage collected.
"A slice describes a piece of an array" which implies the array needs to be there for the slice to exist and can not get collected by GC; as long as some code is pointing at the slice.
I have a trivial kernel running on OS X that returns a single int. The essential bits are:
cl_int d;
cl_int* dptr = &d;
void* dev_d = gcl_malloc(sizeof(cl_int),NULL,CL_MEM_WRITE_ONLY);
// ... stuff to setup dispatch queue
dispatch_sync(queue, ^{
// ... running the kernel stuff
gcl_memcpy((void*)&d, dev_d, sizeof(cl_int)); // this gives d==0
gcl_memcpy((void*)dptr, dev_d, sizeof(cl_int)); // this gives correct d
});
Question is, what is the difference between &d and dptr? I've always thought of them as essentially interchangeable, but gcl_memcpy seems to be making a distinction. Any ideas? I can obviously just use the dptr solution, but I'm still curious what's happening.
I don't think this has to do with the gcl_memcpy call specifically. I think it has to do with your GCD call.
When you call dispatch_sync, your block gets a copy of the variables you use in it. In fact, in similar situations, I get a warning from my compiler about using &d in the block, since it's probably a common mistake.
So in your main function you have a variable d at Address1 with value 0 and a variable dptr at Address2 with value Address1. In your dispatch block you have a variable d at Address3 with value 0 and a variable dptr at Address4 with value Address1. So when you write to &d within your dispatch block, you are putting the value in Address3 which you won't see outside of your dispatch block. When you write to dptr in your dispatch block, you are putting the value in Address1, which is what you expect.
Or to put it another way, your call to dispatch_queue is like calling a function defined like
void myfunction(cl_int d, cl_int* dptr).
If you're skeptical of my answer, I suggest you try this with a simple assignment instead of the gcl_malloc call.
i'm having some issues on bison (again).
I'm trying to pass a string value between a "recursive rule" in my grammar file using the $$,
but when I print the value I have passed, the output looks like a wrong reference ( AU�� ) instead the value I wrote in my input file.
line: tok1 tok2
| tok1 tok2 tok3
{
int len=0;
len = strlen($1) + strlen($3) + 3;
char out[len];
strcpy(out,$1);
strcat(out," = ");
strcat(out,$3);
printf("out -> %s;\n",out);
$$ = out;
}
| line tok4
{
printf("line -> %s\n",$1);
}
Here I've reported a simplified part of the code.
Giving in input the token tok1 tok2 tok3 it should assign to $$ the out variable (with the printf I can see that in the first part of the rule the out variable has the correct value).
Matching the tok4 sequentially I'm in the recursive part of the rule. But when I print the $1 value (who should be equal to out since I have passed it trough $$), I don't have the right output.
You cannot set:
$$ = out;
because the string that out refers to is just about to vanish into thin air, as soon as the block in which it was declared ends.
In order to get away with this, you need to malloc the storage for the new string.
Also, you need strlen($1) + strlen($3) + 4; because you need to leave room for the NUL terminator.
It's important to understand that C does not really have strings. It has pointers to char (char*), but those are really pointers. It has arrays (char []), but you cannot use an array as an aggregate. For example, in your code, out = $1 would be illegal, because you cannot assign to an array. (Also because $1 is a pointer, not an array, but that doesn't matter because any reference to an array, except in sizeof, is effectively reduced to a pointer.)
So when you say $$ = out, you are making $$ point to the storage represented by out, and that storage is just about to vanish. So that doesn't work. You can say $$ = $1, because $1 is also a pointer to char; that makes $$ and $1 point to the same character. (That's legal but it makes memory management more complicated. Also, you need to be careful with modifications.) Finally, you can say strcpy($$, out), but that relies on $$ already pointing to a string which is long enough to hold out, something which is highly unlikely, because what it means is to copy the storage pointed to by out into the location pointed to by $$.
Also, as I noted above, when you are using "string" functions in C, they all insist that the sequence of characters pointed to by their "string" arguments (i.e. the pointer-to-character arguments) must be terminated with a 0 character (that is, the character whose code is 0, not the character 0).
If you're used to programming in languages which actually have a string datatype, all this might seem a bit weird. Practice makes perfect.
The bottom line is that what you need to do is to create a new region of storage large enough to contain your string, like this (I removed out because it's not necessary):
$$ = malloc(len + 1); // room for NUL
strcpy($$, $1);
strcat($$, " = ");
strcat($$, $3);
// You could replace the strcpy/strcat/strcat with:
// sprintf($$, "%s = %s", $1, $3)
Note that storing mallocd data (including the result of strdup and asprintf) on the parser stack (that is, as $$) also implies the necessity to free it when you're done with it; otherwise, you have a memory leak.
I've solved it changin the $$ = out; line into strcpy($$,out); and now it works properly.
I have a static function:
void TextManager::printDialogue(vector<Button*>* options, int optionsCount, vector<string> outputDisplayText)
{
active = true;
buttons = *options;
buttonsCount = optionsCount;
outputText = outputDisplayText;
}
The "buttons" variable is static:
static vector<Button*> buttons;
I make a call to printDialogue in an execute function:
void WorldDoor::execute()
{
vector<Button*> buttons;
buttons.push_back(new CancelButton());
buttons.push_back(new ChangeRoomButton(room));
TextManager::printDialogue(&buttons, 2, messages); //<----
std::vector<Button*>::iterator i = buttons.begin();
for ( i = buttons.begin() ; i < buttons.end(); i++ )
{
delete * i;
}
}
For whatever reason, when I debug and have a break point inside of the printDialogue function, the values in "buttons" are perfectly fine. However, after I leave printDialogue, the strings contained in my buttons go from being readable to giving me an error message saying:
I tried passing a pointer to an array instead of using
vector<Button*>
but it was only reading the first variable. Now it is not reading anything. Could anyone please help?
There is a static member variable called buttons, and also a local variable inside execute() called buttons. You should rename to avoid confusion, otherwise, the local variable will be used instead of the static member variable inside execute().
Edit: Completely misunderstood the question.
When you do this:
vector<int*> vector1;
vector<int*> vector2;
vector1.push_back(new int(5));
vector2 = vector1;
It copies the pointers, not the value of the pointers.
So when you later iterate over the first vector and delete the dynamic memory, both vectors have pointers pointing to the same memory that you deleted, so your second vector is pointing to invalid memory.
If you are using C++11, you can use a vector of unique pointers, and std::move() one vector into another.
Otherwise, you can just call 'clear()' on the vector, without deleting the memory.
Here's how the function could be written:
void TextManager::printDialogue(vector<Button*>* options, int optionsCount, vector<string> outputDisplayText)
{
active = true;
buttons = *options;
options->clear(); //<--- Instead of crawling over it and delete-ing it.
buttonsCount = optionsCount;
outputText = outputDisplayText;
}
Everything below this was my misunderstanding the question: (contains other information that might be important)
When you do:
vector<Button*> buttons;
Inside the function, you are creating a new vector called 'buttons', which gets destroyed at the end of the function call.
If you want to access the global one, don't create a new one inside the function, or name them something different.
Example:
int myVar = 100; //Declares a variable called 'myVar' at global scope.
void func()
{
int myVar = 200; //Declares a *different* variable called 'myVar' at function scope.
std::cout << myVar << std::endl; //Prints the one inside the function, not the one outside it.
}
By the way, the variable 'static' shouldn't be used at global scope, unless the variable belongs to a class.
To make a variable global, you just put it outside of any function. To make a class member shared between all instances of that class, you declare it static so that class knows to have all instances share the one variable. It's a different thing. =)
If you have your code split into multiple files, to make a global really-truly global, you have to declare it 'extern' in your header, and not extern in one source file, and have other source files #include the header that externs it. Slightly clunky, but that's how it's done. They are working on a better system for it, but it'll be several years before it becomes standardized.