pointer to an array of pointes of c-style strings c++/cli - pointers

I couldn't find a reason for this problem.
The function getfruits returns a pointer to an array of pointes of c-style strings.
Main tries to access the c-style strings.
using namespace System;
#pragma managed
void getfruits(char ***list, int* count)
{
char *txt[] =
{
"apple",
"orange",
"pears",
"banana",
};
*list = txt;
*count = 4;
}
#pragma managed
int main(array<System::String ^> ^args)
{
char **lst; int cnt;
getfruits(&lst,&cnt);
char *t; int i;
String^ s;
for (i=0; i<cnt; i++)
{
t = lst[i]; //t = <undefined value>
s = gcnew String(t);
Console::WriteLine("Fruit = {0}", s);
};
Console::ReadKey();
return 0;
}
But it gets instead of pointers to the c-style strings.
Eventually,
An unhandled exception of type 'System.AccessViolationException' occurred in arraysandclasses.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What's going wrong? Can somebody point out anything? The code should simply compile if copied and pasted. Thanks in advance.

You've returned the address of a local array and used it. That's undefined behavior. txt has automatic storage duration and gets destroyed as soon as you leave the getfruit function. But you keep a pointer to it and use it, but the pointed memory no longer contains a living object. I suggest that you should perhaps read a good C++ book.

Related

Swap memory pointers atomically on CUDA

I have two pointers in memory and I want to swap it atomically but atomic operation in CUDA support only int types. There is a way to do the following swap?
classA* a1 = malloc(...);
classA* a2 = malloc(...);
atomicSwap(a1,a2);
When writing device-side code...
While CUDA provides atomics, they can't cover multiple (possibly remote) memory locations at once.
To perform this swap, you will need to "protect" access to both these values with something like mutex, and have whoever wants to write values to them take a hold of the mutex for the duration of the critical section (like in C++'s host-side std::lock_guard). This can be done using CUDA's actual atomic facilities, e.g. compare-and-swap, and is the subject of this question:
Implementing a critical section in CUDA
A caveat to the above is mentioned by #RobertCrovella: If you can make do with, say, a pair of 32-bit offsets rather than a 64-bit pointer, then if you were to store them in a 64-bit aligned struct, you could use compare-and-exchange on the whole struct to implement an atomic swap of the whole struct.
... but is it really device side code?
Your code actually doesn't look like something one would run on the device: Memory allocation is usually (though not always) done from the host side before you launch your kernel and do actual work. If you could make sure these alterations only happen on the host side (think CUDA events and callbacks), and that device-side code will not be interfered with by them - you can just use your plain vanilla C++ facilities for concurrent programming (like lock_guard I mentioned above).
I managed to have the needed behaviour, it is not atomic swap but still safe. The context was a monotonic Linked List working both on CPU and GPU:
template<typename T>
union readablePointer
{
T* ptr;
unsigned long long int address;
};
template<typename T>
struct LinkedList
{
struct Node
{
T value;
readablePointer<Node> previous;
};
Node start;
Node end;
int size;
__host__ __device__ void initialize()
{
size = 0;
start.previous.ptr = nullptr;
end.previous.ptr = &start;
}
__host__ __device__ void push_back(T value)
{
Node* node = nullptr;
malloc(&node, sizeof(Node));
readablePointer<Node> nodePtr;
nodePtr.ptr = node;
nodePtr.ptr->value = value;
#ifdef __CUDA_ARCH__
nodePtr.ptr->previous.address = atomicExch(&end.previous.address, nodePtr.address);
atomicAdd(&size,1);
#else
nodePtr.ptr->previous.address = end.previous.address;
end.previous.address = nodePtr.address;
size += 1;
#endif
}
__host__ __device__ T pop_back()
{
assert(end.previous.ptr != &start);
readablePointer<Node> lastNodePtr;
lastNodePtr.ptr = nullptr;
#ifdef __CUDA_ARCH__
lastNodePtr.address = atomicExch(&end.previous.address,end.previous.ptr->previous.address);
atomicSub(&size,1);
#else
lastNodePtr.address = end.previous.address;
end.previous.address = end.previous.ptr->previous.address;
size -= 1;
#endif
T toReturn = lastNodePtr.ptr->value;
free(lastNodePtr.ptr);
return toReturn;
}
__host__ __device__ void clear()
{
while(size > 0)
{
pop_back();
}
}
};

Using valgrind - "Invalid read of size 1" for strlen

I'm trying to write code that sets the name of a Student object to a new name, but I'm coming across memory leak errors when creating a character array. I assume it has to do with /0 at the end of the array and isn't terminating properly, but I don't know how to properly fix this. Thanks for the help.
#include "student.h"
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
Student::Student(const char * const name, int perm) {
this->setName(name);
this->setPerm(perm);
}
int Student::getPerm() const {
return this->perm;
}
const char * const Student::getName() const {
return this->name;
}
void Student::setPerm(const int perm) {
this->perm = perm;
}
void Student::setName(const char * const newName) {
this->name = new char[strlen(newName)+1];
// this->name[srtlen(newName)+1] = '/0'; <---- My suggested fix, but doesn't work
strcpy(this->name,newName);
}
Student::Student(const Student &orig) {
this->setName(orig.getName());
this->setPerm(orig.getPerm());
}
Student::~Student() {
delete this->name;
this->perm = 0;
}
This is the valgrind error:
==13814== Invalid read of size 1
==13814== at 0x4C2BA12: strlen (vg_replace_strmem.c:454)
==13814== by 0x4F56FD6: UnknownInlinedFun (char_traits.h:267)
==13814== by 0x4F56FD6: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (basic_string.h:456)
==13814== by 0x401ED8: Student::toString[abi:cxx11]() const (student.cpp:64)
==13814== by 0x401A46: main (testStudent00.cpp:14)
==13814== Address 0x5302e8 is not stack'd, malloc'd or (recently) free'd
==13814==
Your assumption that you needed to add the 0 terminator is wrong, strcpy() will do that for you. Your attempt of doing so adds the 0 terminator one byte past the space you allocated (remember, array indexes start at zero), and the syntax is also wrong, you would need to do:
this->name[strlen(newName)] = '\0';
However, to fix your memory leak You need to delete the previous string, like
void Student::setName(const char * const newName)
{
delete [] this->name;
this->name = new char[strlen(newName)+1];
strcpy(this->name,newName);
}
Student::Student(const Student &orig) :
name(0) {
this->setName(orig.getName());
this->setPerm(orig.getPerm());
}
Student::~Student() {
delete [] this->name;
this->perm = 0;
}
Now, for this to work, you also need to fix your constructor and copy constructor to initialize the name member, so it isn't an uninitialized pointer for the first call to the setName() function, and you need to add an assignment operator too, so you can properly handle assignments.
Student::Student(const char * const name, int perm) :
name(0)
{
this->setName(name);
this->setPerm(perm);
}
Student &operator=(const Student &orig) {
this->setName(orig.getName());
this->setPerm(orig.getPerm());
}
Also, consider using std::string instead of your current low level way of handling strings, that way you don't need to even implement a copy constructor, assignment operator and destructor for this class, nor deal with correctly managing memory.

passing different structure type in c for functions

I have a following code :
typedef struct PStruct{
int len;
char* data;
}PointerStruct;
typedef struct AStruct{
int len;
char data[256];
}ArrayStruct;
void checkFunc(PointerStruct* myData)
{
if (0 == myData || 0 == myData->data){
printf("error\n");
}
}
int main()
{
ArrayStruct my_data;
my_data.len = 256;
char data[] = "data is sent";
my_data.data = &data;
checkFunc((PointerStruct*)my_data);
return 0;
}
is there any wrong in passing structure which has array. where as the required is pointer.
please let me know.
There are a couple of points to be considered in your program.
char data[] = "data is sent";
This is a character array of 13 characters. Hence, my_data.data = &data; will give a compilation error as shown below
error: incompatible types when assigning to type 'char[256]' from type 'char (*)[13]'
To copy your string, you could probably use strcpy as shown below
strcpy(my_data.data, data);
Next point is passing the pointer to the object. In this call, checkFunc((PointerStruct*)my_data);, you are passing the instance of the object to the function call, but are type-casting as a pointer. You would face compilation issues due to the mismatch of the datatypes as error: cannot convert to a pointer type
To overcome this error, you should pass a reference to your my_data object as checkFunc((PointerStruct*) &my_data);. Hence, your new main function would look like
int main()
{
ArrayStruct my_data;
my_data.len = 256;
char data[] = "data is sent";
//my_data.data = &data;
strcpy(my_data.data, data); // Use of strcpy. You would require to include <string.h>
checkFunc((PointerStruct*)(&my_data)); // Pass a reference and not by value
return 0;
}
With these changes, your code should work fine.

Pointers to stack

I am sorry that I cannot support my question with some code (I didnt understand how to structure it so it would be accepted here), but I try anyway.
If I understand correctly, a struct that references a struct of same type would need to do this with contained pointer for reference. Can this pointer reference to allocated space on the stack (instead of the heap) without creating segmentation fault? -
how should this be declared?
Yes, you can use pointers to variables on the stack, but only when the method that provides that stack frame has not returned. For example this will work:
typedef struct
{
int a;
float b;
} s;
void printStruct(const s *s)
{
printf("a=%d, b=%f\n", s->a, s->b);
}
void test()
{
s s;
s.a = 12;
s.b = 34.5f;
printStruct(&s);
}
This will cause an error however, as the stack frame would have disappeared:
s *bad()
{
s s;
s.a = 12;
s.b = 34.5f;
return &s;
}
EDIT: Well I say it will cause an error, but while calling that code with:
int main()
{
test();
s *s = bad();
printStruct(s);
return 0;
}
I get a warning during compilation:
s.c:27:5: warning: function returns address of local variable [enabled by default]
and the program appears to work fine:
$ ./s
a=12, b=34.500000
a=12, b=34.500000
But it is, in fact, broken.
You didn't say what language you are working in, so assuming C for now from the wording of your question... the following code is perfectly valid:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t str1;
str_t str2;
str1.pNext = &str2;
In this example both str1 and str2 are on the stack, but this would also work if either or both were on the heap. The only thing you need to be careful of is that stack variables will be zapped when they go out of scope, so if you had dynamically allocated str1 and passed it back out of a function, you would not want str1->pNext to point to something that was on the stack within that function.
In other words, DON'T DO THIS:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t *func(void)
{
str_t *pStr1 = malloc(sizeof(*pStr1));
str_t str2;
pStr1->pNext = &str2;
return pStr1; /* NO!! pStr1->pNext will point to invalid memory after this */
}
Not sure if this is specifically a C/C++ question, but I'll give C/C++ code as example in anyway.
The only way you can declare it: (with minor variations)
typedef struct abc
{
struct abc *other;
} abc;
other can point to an object on the stack as follows:
abc a, b; // stack objects
b.other = &a;
This is not a question about scope, so I'll skip commenting on possible issues with doing the above.
If, however, you want to assign it to a dynamically created object, there's no way this object can be on the stack.
abc b;
b.other = malloc(sizeof(abc)); // on the heap

"incompatible pointer type" compiling in C

My code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void getData(short int *number, char *string)
{
printf("\nPlease enter a number greater than zero: ");
scanf("%hd", number);
printf("Please enter a character string: ");
scanf("%s", string);
}
void echoPair(short int *number, char *string)
{
printf("Number: %hd Character(s): %s\n", *number, string);
}
int main()
{
short int *number = 0;
char string[32] = {0};
printf("This program will ask you to enter a number greater than zero and \na character string with less than 32 characters \ninput.");
getData(&number, &string);
echoPair(&number, &string);
return(0);
}
The code works fine, but I receive these compiler warnings
warning: passing argument 1 of ‘getData’ from incompatible pointer type
warning: passing argument 2 of ‘getData’ from incompatible pointer type
warning: passing argument 1 of ‘echoPair’ from incompatible pointer type
warning: passing argument 2 of ‘echoPair’ from incompatible pointer type
If do this
getData(number, string);
echoPair(number, string);
The warnings go away, but the program gets a "Segmentation fault: 11" after I enter the first number in the getData function.
Anyone know how to remove the warnings and keep the program working?
Thanks
There are a number of problems here.
First, the line:
short int *number = 0;
should be:
short int number = 0;
Because you used the former, it gave you a null pointer to a short. That's not what you want since the first dereference of that beast will probably crash your code (or, worse, not crash your code but cause strange behaviour).
Secondly, you don't need to pass in the address of strings, they automatically decay to an address, so change:
getData (&number, &string);
echoPair (&number, &string);
to:
getData (&number, string);
echoPair (&number, string); // but see last point below.
And, last of all, you don't need to pass in the address just to print it, you can just pass in the value, hence:
echoPair (&number, &string);
becomes:
echoPair (number, string);
As a whole, I think what you want is:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void getData(short int *number, char *string) {
printf("\nPlease enter a number greater than zero: ");
scanf("%hd", number);
printf("Please enter a character string: ");
scanf("%s", string);
}
void echoPair(short int number, char *string) {
printf("Number: %hd Character(s): %s\n", number, string);
}
int main (void) {
short int number = 0;
char string[32] = {0};
printf("Blah blah ...");
getData(&number, string);
echoPair(number, string);
return(0);
}
As an aside, you don't ever want to see unbounded string scans like:
scanf ("%s", string);
in production-ready code. It's a buffer overflow vulnerability waiting to happen, since you don't control what the user will input. In your particular case, the user entering more than (about) 30 characters may cause all sorts of weird behaviour.
The scanf function is for scanning formatted text, and there's not many things more unformatted than user input :-)
If you want a robust user input function, see here.
You declare the local variable number as a pointer to short int. You then pass a pointer to it to getData and echoPair. So you're passing a pointer to a pointer, which is the wrong type. Probably you want to declare number as just a short int rather than a pointer.

Resources