Clear out the STL list of pointers in C++ - c++

I have defined a list of pointers. How should I free all these pointers before clearing the list? What is the best approach to erase all list members? In below program, is it required to free memory allocated for struct?? See my inline comments.
struct MyStruct {
char *data;
int len;
};
typedef std::list<struct MyStruct *> myStruct_list;
myStruct_list l_list;
/* Prepare a list */
for( int i = 0; i < 10; i++) {
struct MyStruct *s = (MyStruct *)malloc(sizeof(struct MyStruct));
s->data = (char*)malloc(MAX_LEN);
get_random_data(s->data,size);
s->len = strlen(s->data);
l_list.push_back(s);
}
/* Delete all members from a list */
myStruct_list::iterator it;
for (it = l_list.begin(); it != l_list.end(); ++it) {
if (*it) {
free(*it); // --->> do I need to free (*it)->data ?????
}
}
l_list.clear();

I want to understand is there any memory leak in below program?
Yes you have it right here:
p = (char*)malloc(MAX_LEN);
p = (char *)buf;
you allocate memory and assign it to p and next line you loose it. So:
You should not use malloc() in C++ programs unless you need to pass data that would be managed by C code
You should use special data structure like std::string etc to manage your data.
If you still need to allocate dynamic memory use smart pointers.
How should I debug if there is any memory leak?
You would not create them in the first place. For example, how could you write get_random_str (assuming you really have to allocate it using malloc):
using spchar = std::unique_ptr<char[], decltype(std::free) *>;
spchar get_random_str( int len )
{
spchar s( static_cast<char *>( malloc( len + 1 ) ), std::free );
static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = '\0';
return s;
}
Note, I did not compile this code, it's to show you the idea.
Update: looks like you think that this code:
p = (char *)buf;
would copy string from buf to p, which is not the case. Instead you make p point to memory of buf loosing old value that malloc() returned before (hence creating memory leak) and you assign that adress of buf to data which leads to UB when you call free() on it, so what you need instead:
strncpy( p, buf, MAX_LEN );
but even that is not necessary as you do not really need buf at all:
void myClass::fillData(void)
{
s = (MyStruct *)malloc(sizeof(struct MyStruct));
s->data = (char*)malloc(MAX_LEN);
get_random_str(s->data,950);
s->len = strlen(s->data);
l_list.push_back(s);
}
but this is more C code, using some C++ syntax. You should get newer compiler and textbook if you really want to learn C++.

Delete elements using lambda function in for_each:
std::for_each(l_list.begin(), l_list.end(), [](const MyStruct* elem){if(elem) free(elem)});
And clear pointers:
l_list.clear();

Related

Is it safe to delete a void* byte by byte?

Because i don't know verry much about memory allocation, I would like to know if it safe to delete a block of consecutive bytes (array) like this.
void Free(void* ptr, size_t cbSize)
{
if (cbSize == 0) return;
if (ptr == NULL) return;
for(size_t i = cbSize; i > 0; i--)
{
char* p = &((char*)ptr)[i];
delete p;
}
char* p = (char*) (ptr);
delete p;
}
I have tried this method in the following circumstances and got no error.
int* a = new int[100];
Free(a, 100 * sizeof(int));
int* a = (int*) malloc(100 * sizeof(int));
Free(a, 100 * sizeof(int));
You always delete what you allocate; exactly and only what you allocate. If you new a single thing, you delete a single thing. The fact that the "single thing" happens to take up more than one byte is irrelevant; you delete what you new.
How can i make my function work in this case ?
You don't. You newed an array of ints. So you must delete an array of ints. Types matter in C++.

C++ Where is the seg fault?

I am currently tackling this assignment for my computer science class:
Make your own dynamic array template. It should allow creating contiguous arrays (filled with things of the same type) which you can extend without worrying about running out of space.
Do one version using malloc and free.
Do one version using new and delete.
My version using new and delete works flawlessly; however, in trying to convert my new/delete code to using malloc/free, I keep getting a seg fault. I have narrowed down the segfault (I think), to being in a single function: addData. Take a look at the code in my main I used to test this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3->addData(7);
testArray4->printArray();
return 0;
This gives a seg fault; however, when I change it to this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3; //->addData(7);
testArray4->printArray();
return 0;
There is no seg fault. This makes me believe the issue is in my addData function. Here is the code for that:
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
I am new to programming as a whole and have not completely wrapped my head around pointers and memory allocation, etc. Any advice you could give me would be greatly appreciated! In case you need to see the rest of the code, here is the entire file I coded my template in. Thank you so much for your time!
#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;
template<typename T>
class Array2{
public:
Array2(int size){
this->size = size;
data = (T *) malloc(sizeof(T)*size);
};
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
~Array2(){
free(this->data);
};
void initArray(){
for (int i = 0; i < this->size; ++i){
//this->data[i] = i;
this->setData(i, i);
}
};
void printArray(){
//ostringstream oss;
string answer = "";
for (int i = 0; i < this->size; ++i){
//oss << this->data[i] + " ";
cout << this->data[i] << " ";
}
//answer = oss.str();
cout << answer << endl;
};
T* getData(){
return this->data;
}
int getSize(){
return this->size;
}
void setData(T data, int index){
this->getData()[index] = data;
}
private:
int size;
T* data;
};
Array2 <T> *tmp;
Allocates a pointer. This does not point the pointer at anything or allocate any storage for the pointer to point at. What it points at without being explicitly assigned is undefined. If you are lucky, and you are this time, tmp points at an invalid location and the program crashes. If you are unlucky, tmp points at some usable region of program memory and lets you write over it, destroying whatever information was there.
tmp->data = this->getData();
Attempts to access the data member at tmp, but fortunately for you the access is in invalid memory and the program comes to a halt. It also has tmp's data pointing at this's data, and that's a dangerous position to be in. Changes to one will happen to the other because they both use the same storage. Also think about what will happen to this->data if you free tmp->data.
Or perhaps I'm wrong and the halt is here for the same reason:
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
Both need to be fixed. tmp doesn't have to live long, so we can make it a temporary local variable.
Array2 <T> tmp;
Typically this will be created on the stack and destroyed when the function ends and tmp goes out of scope.
But this will not work because Array2's constructor requires a size so it can allocate the array's storage. You need to find out how big to make it. Probably something along the lines of:
Array2 <T> tmp(this->size + 1);
But frankly I don't think you need tmp at all. You should be able to copy the dataToAdd directly into newData without using tmp as an intermediary.
newData is eventually going to be returned to the caller, so it needs a longer scope. Time to use new.
Array2 <T> *newData = new Array2 <T>(this->size + 1);
And through the magic of the constructor... Wait a sec. Can't use new. That makes this hard. malloc doesn't call constructors, so while malloc will allocate resources for newData, it doesn't do the grunt work to set newData up properly. Rule of thumb is Never malloc An Object. There will be exceptions I'm sure, but you shouldn't be asked for this. I recommend using new here and politely telling the instructor they are on crack if they complain.
Anyway, new Array2 <T>(this->size + 1) will allocate the data storage for you with it's constructor.
There is an easier way to do this next bit
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
Try:
for (int i = 0; i < tmp->size; ++i){
newData->data[i] = tmp->data[i]; // you were right here
}
newData->data[tmp->size] = dataToAdd;
And back to something I hinted at earlier:
free(tmp->data);
free(this->data);
Both tmp->data and this->data point to the same memory. To be honest I'm not sure what happens if you free the same memory twice, but I doubt it's good. Regardless, I don't think you want to free it. That would leave this in a broken state.
Recap and fixes
Array2<T> *addData(T dataToAdd)
{
Array2 <T> *newData = new Array2 <T>(this->size + 1);
for (int i = 0; i < this->size; ++i)
{
newData->data[i] = this->data[i];
}
newData->data[this->size] = dataToAdd;
return newData;
};
This version leaves this intact and returns a newData that is one bigger than this. What it doesn't do is add anything to this. Which is goofy for a method named addData.
It also leads to stuff like this:
mydata = myData->addData(data);
which leaks memory. The original mydata is lost without deletion, resulting in a memory leak.
What I think you really need is a lot simpler:
Array2<T> & addData(T dataToAdd)
{
this->data = realloc(this->data, this->size + 1);
this->data[this->size] = dataToAdd;
this->size++;
return *this;
};
realloc effectively allocates a new buffer, copies the old buffer into the new one, and frees the old buffer all in one fell swoop. Groovy.
We then add the new element and increment the count of elements stored.
Finally we return a reference to the object so it can be used in a chain.
Usage can be
myData.addData(data);
myData.addData(data).addData(moredata);
myData.addData(data).printArray();
and if you have operator << support written
std::cout << myData.addData(data) << std::endl;
I'd go back over the new version of Array if I were you. Most of the bugs picked off here are conceptual errors and also apply to it. You might just be getting unlucky and it merely looks like it works. I just read C++ Calling Template Function Error. The posted solutions fixed the immediate problem, but did not touch the underlying memory management problems.
As for the rest of your class, I advice following the link and answering What is The Rule of Three? Because Array2 violates the heck out of it.

realloc pointer change when out of function

i am starting homework about dynamic array, first, I have a 2 dimensional array :
int initializeInfo[3][4] ={{77,68,0,0},{96,87,89,78},{70,90,86,0}};
and use pointer to store it:
int **ptr = (int**)malloc(3*sizeof(int));
int size = 0;
for(int i =0;i<3;i++){
addInitiazeInfo(ptr,initializeInfo[i],size);
}
here is function addInitiazeInfo:
void addInitiazeInfo(int**& ptr, int arr[],int& size){
ptr[size] = (int*)malloc(4*sizeof(int));
if(ptr[size] == NULL){
return;
}
ptr[size] = arr;
size++;
}
It's run OK! The 2 dimensional array is store by ptr pointer.
And I want to add new row, I think realloc is needed, then I try:
int arr[] = {3,4,5,6};
size++;
ptr = (int**)realloc(ptr,size * sizeof( int ) );
ptr[size-1] = (int*)malloc(4*sizeof(int));
ptr[size-1] = arr;
But I think this is my trouble, the output make me hard to know how it happend:
please help me, thanks everyone
When you do
ptr[size] = arr;
You are essentially assigning the address of arr, to ptr[size]. This means that the memory you just allocated is lost and successfully leaked.
You want to manually copy element by element or use something like memcpy. It is likely this might fix your issue, depending on the rest of your code.

VC++: Pass multiple arrays between functions

I'm quite new to VC++, and I need to pass 4 arrays between functions, so I'm using another array to store their pointers. Have I done it correctly?
unsigned int* step1(...) {
...
// save data arrays
unsigned int* savedData = new unsigned int[4];
savedData[0] = *data0;
savedData[1] = *data1;
savedData[2] = *data2;
savedData[3] = *data3;
return savedData;
}
unsigned char* step2(unsigned int* savedData, ...) {
// read data arrays
unsigned int* data0 = &savedData[0];
unsigned int* data1 = &savedData[1];
unsigned int* data2 = &savedData[2];
unsigned int* data3 = &savedData[3];
...
}
In order to complete the previous valid answers, I will try to expand the answer:
Have I done it correctly?
Well, in order to pass data between functions: yes, doing it with pointers is an option. But it is commonly discouraged by the community because it makes troublesome the memory management.
When you work with pointers pointing dynamic memory, you must have a clear image of WHERE the memory is created and WHERE the memory will be deleted, in other words: the cycle of life of the memory must be clear and straightforward and for this reason, pass pointers between functions is commonly discouraged.
For example, in your case: the unsigned int* step1(...) function returns a pointer but looking at it, a new programmer or someone that works with you wouldn't tell if the pointer returned is dynamic memory and if calling step1 must delete or delete [] the memory after the call, same goes for unsigned char* step2(unsigned int* savedData, ...) and would be more confusing and troublesome because someone would ask: step2 would alter the savedData passed?
In order to fix the step2 issue, you can change the function to:
unsigned char* step2(const unsigned int* const savedData, ...)
By adding the const you're telling: "Hey! step2 isn't going to alter the contents of savedData nor changing the address it is pointing to".
But all the previous text is useless because doesn't fix the most important problem: Where the memory is freed?
In the step1 you're creating memory dynamically, in the step2 this memory is readed but... the delete is hidden somewhere in the code that you don't paste? or there is a step3 waiting for take care of the memory?
To avoid all this memory headaches, is commonly advised the use of STL containers, like std::vector, the container will take care of the memory management for you, in your case:
typedef std::vector<int> intvector;
typedef std::vector<intvector> intintvector;
void step1(intintvector &Data, ...) {
...
// create data arrays
intvector data0, data1, data2, data3;
// fill data0, data1, data2, data3
// ...
// save data arrays.
Data.push_back(data0);
Data.push_back(data1);
Data.push_back(data2);
Data.push_back(data3);
}
void step2(const intintvector &savedData, ...) {
// read data arrays
intvector data0 = savedData[0];
intvector data1 = savedData[1];
intvector data2 = savedData[2];
intvector data3 = savedData[3];
// ...
}
In brief summary: You aren't using correctly the pointer part if you don't take care of the dynamic memory, so, you must fix this issue or delegate into STL containers.
Hope it helps! :D
Use std::vector.
std::vector<int> data;
data.push_back(data0);
data.push_back(data1);
data.push_back(data2);
data.push_back(data3);
And
int data0 = data[0];
int data1 = data[1];
int data2 = data[2];
int data3 = data[3];
And add some code, where these functions will be used.
You will need an array of pointers, for example:
//The function that takes the array
void foo( char ** data )
{
std::cout << data[0];
std::cout << data[1];
std::cout << data[2];
}
main()
{
char * str = "aaa";
char * str1 = "sss";
char * str2 = "ddd";
char ** res = new char *[3];//here's your array that has 3 elements each of which is a pointer.
res[0]=str;
res[1]=str1;
res[2]=str2;
foo( res );
return 0;
}
The output will be
aaasssddd
A slightly better way:
It would be better to use stl containers instead of raw pointers since they are easier and safer to use. With pointers, it will work the same way:
void foo( std::vector< char * >vec )
{
std::cout << vec[0];
std::cout << vec[1];
std::cout << vec[2];
}
main()
{
char * str = "aaa";
char * str1 = "sss";
char * str2 = "ddd";
std::vector< char * >vec;
vec.push_back(str);
vec.push_back(str1);
vec.push_back(str2);
foo( vec );
return 0;
}
A further improved way:
And finally, the best way is to use strings:
void foo( std::vector< std::string >vec )
{
std::cout << vec[0];
std::cout << vec[1];
std::cout << vec[2];
}
main()
{
std::string str = "aaa";
std::string str1 = "sss";
std::string str2 = "ddd";
std::vector< std::string >vec;
vec.push_back(str);
vec.push_back(str1);
vec.push_back(str2);
foo( vec );
return 0;
}
Assuming you really want what you've written in question (4 arrays grouped into one), first of all you need 4 arrays, for example int:
int data1[] = {1,2,3,4};
int data2[] = {5,6,7,8,9,10};
int *data3; // Let's say those two were allocated by malloc/new
int *data4;
// Now array that will contain those values
int **data = new (int*)[4]; // int * = your datatype (array of ints)
// (int*)[] = array of arrays of ints
data[0] = data1;
data[1] = data2;
data[2] = data3;
data[3] = data4;
// And reverse function
data1 = data[0];
data2 = data[1];
data3 = data[2];
data4 = data[3];
Few notes:
if you want to have those "arrays" resizeable use (or use more than 4 items after time) use std::vector or another STL Container
if those data chucks have any special meaning (like data1 = user ids, data2 = visitor ids, ...) build class or structure that will name them:
// In C:
struct user_data{
int *user_ids;
int *visitor_ids;
char **unregistered_user_names; // Feel free to use another types
}
// In C++
class UserData {
std::vector<int> userIds;
std::vector<int> visitorIds;
std::vector<std::string> unregisteredUserNames;
}
Once allocated data with new unsigned int [4] don't forget free memory with delete [] array
I tried Vyktor's solution but it didn't work. I finally got it working using plain ol' arrays (no STL/vectors) and using the following code to save/load arrays from another parent array.
Note that this approach is considered "legacy" since you have to unallocate the arrays manually using the delete [] myArray syntax.
unsigned int** step1(...) {
...
// save data arrays
unsigned int** savedData = new unsigned int*[4]; // ** means pointer to a pointer
savedData[0] = data0; // transfer the pointer value straight
savedData[1] = data1;
savedData[2] = data2;
savedData[3] = data3;
return savedData;
}
unsigned char* step2(unsigned int** savedData, ...) { /// input is pointer to pointer
// read data arrays
unsigned int* data0 = savedData[0]; // read pointer straight
unsigned int* data1 = savedData[1];
unsigned int* data2 = savedData[2];
unsigned int* data3 = savedData[3];
...
}

Returning array of dynamically allocated wchar_t* from a function

I have a function whose signature is as follows:
GetCustomers( wchar_t** Name,int *count);
In main method: Call to customer looks like this:
GetCustomers( Name,&count);
The body of the function is as follows: (since count of customers is unknown , I am trying to allocate meomry dynamically)
GetCustomers( wchar_t** Name,int *count)
{
//Logic to get customer count : Stored in int myCustomersCount
Names = new wchar_t*[myCustomersCount];
for (int i=0; i < myCustomersCount; i++ )
{
Names[i] = new wchar_t;
}
//Logic to get customer names in wchar_t* strName = "Name1";
Names[0] = strName;
*count = myCustomersCount;
}
I would think that this implementation would allow array Name to be passed back correctly to the Main() function with memory allocation on heap but it seems not to work. What is wrong here? myCustomersCount seems to be correct in caller.
PS: The code compile and executes but array received in Main is garbage.
You seem to be thinking in terms of C, not really C++. I'd use something like:
std::vector<std::string> GetCustomers();
or (probably preferred):
template <class outIt>
void GetCustomers(outIt output_iterator);
The latter you'd use something like:
std::vector<std::wstring> customers;
GetCustomers(std::back_inserter(customers));
The third obvious possibility would be to just equip your customers class with a begin() and end() member functions that return iterators to the customers data.
Edit2: Here's some tested demo code:
#include <stdio.h>
#include <string.h>
#include <wchar.h>
void GetCustomers(wchar_t ***names, int *count) {
static wchar_t *myCustomers[] = {
L"You",
L"Him",
L"Her"
};
int myCustomersCount = 3;
wchar_t **temp = new wchar_t *[myCustomersCount];
*count = myCustomersCount;
for (int i=0; i<myCustomersCount; i++) {
temp[i] = new wchar_t[wcslen(myCustomers[i])+1];
wcscpy(temp[i], myCustomers[i]);
}
*names = temp;
}
int main() {
wchar_t **customers;
int count;
GetCustomers(&customers, &count);
for (int i=0; i<count; i++)
printf("%S\n", customers[i]);
return 0;
}
I'm really not sure what you're trying to do here; from what I understand about your code; you're trying to store some strings into an array of an array of character pointers.
GetCustomers(wchar_t **Name, int *count) {
Name = new wchar_t*[myCustomersCount];
for(int i = 0; i < myCustomersCount; i++) {
/* Get your customer name and store into strName */
Name[i] = strName;
}
*count = myCustomersCount;
}
In main, presumably you've got something like this
wchar_t *Name = NULL;
and then you say
GetCustomers( Name,&count);
This passes Name by value, but you want to pass it by reference:
GetCustomers( &Name,&count);
And presumably it's just a typo, but your parameter name is Name (singular) but you refer to it as Names (plural) in the function:
GetCustomers( wchar_t** Name,int *count)
{
//Logic to get customer count : Stored in int myCustomersCount
Names = new wchar_t*[myCustomersCount];
In any case, you want to assign to where Name is pointing, not to itself:
*Names = new wchar_t*[myCustomersCount];
Then for each element in Names you allocate one character, but then overwrite the first one with strName. The allocation is unnecessary (and in fact is a memory leak), and you should assign from strName to each element within the loop, as Suroot's answer does.
2 definite issue and 1 potential issue with your code. The main issue causing your problem first: Name itself is passed by value. That means when you you assign to it in the very first line of your function when you new the memory, you're assigning to the copy, not the original! You have three options: 1) keep the double pointer, make the caller responsible for allocating the memory, and add a third parameter for number of names that the array can hold (recommended) or 2) make Name a triple pointer (wchar_t*** Name) and then you can assign to it by dereferencing it: *Name = new wchar_t*[myCustomersCount]; or 3) just return the wchar_t** since you don't use the passed value for anything.
Then another definite issue: when you allocate memory for each name, you need to use the new[] operator there as well because otherwise you're only allocating room for a single wchar_t.
Finally, the potential issue. You don't show how exactly this code is getting each customer name. But if strName points to memory that is getting reused for each customer name as you put them all in your array, you're going to have to wstrcpy each name into the array. If it doesn't, then you don't need to allocate memory for each Names[i] as you can just store the result right into Names[i].
A final note: just from looking at this code it seems like you're going to have lots of problems with memory management as it seems very unclear who is responsible for allocating and deallocating memory which is likely going to lead to memory leaks. Try your best to keep the responsibility for allocating and deallocating the memory in the same location and you'll reduce lots of potential headaches -- have callers allocate the memory before they call the function and have the caller deallocate the memory when they're done with it.
/* changed */
wchar_t** GetCustomers( int *count)
{
//Logic to get customer count : Stored in int myCustomersCount
wchar_t **Names = new wchar_t*[myCustomersCount];
for (int i=0; i < myCustomersCount; i++ )
{
/* changed */
Names[i] = new wchar_t[MAX_NAME_SIZE];
}
//Logic to get customer names in wchar_t* strName = "Name1";
Names[0] = strName; /* possible wstrcpy needed here? */
*count = myCustomersCount;
/* changed */
return Names;
}
Edit
If you really absolutely can't change the function signature, the only solution I can think of is to flatten your array and use C memory functions (you could also just use a long series of news and deletes, but why not use realloc when this is what it's made for and you're managing memory without using other C++ features like the STL anyways?):
GetCustomers( wchar_t **Names, int *count)
{
//Logic to get customer count : Stored in int myCustomersCount
size_t names_size = 0;
for (int i=0; i < myCustomersCount; i++ )
{
strName = ???; // whatever you use to get the next name
size_t old_names_size = names_size;
names_size += (wstrlen(strName) + 1) * sizeof(wchar_t); //+1 for NULL
*Names = realloc(*Names, names_size);
if (!*Names) {
// Memory allocation failed, log it, abort, do whatever
}
wstrcpy(Names[old_names_size], strName);
}
*count = myCustomersCount;
}
Note that this assumes that Name has already been initialized and points to memory where you can store a wchar_t*, just like the original version assumed count has been initialized and points to memory where you can store an int.
I thought I'd make a fresh start in a new answer.
Here's a simple program that does what I think you're trying to do, with the constraint that the signature of GetCustomers must not be altered.
void GetCustomers(wchar_t** Names,int *count)
{
// Allocate the array of names
wchar_t **ar = new wchar_t*[3];
// Allocate space for each name in the array
ar[0] = new wchar_t[10];
ar[1] = new wchar_t[10];
ar[2] = new wchar_t[10];
// Fill in the names
wcscpy(ar[0],L"joe");
wcscpy(ar[1],L"jim");
wcscpy(ar[2],L"bob");
// Return the array through the bad GetCustomers signature
*Names = (wchar_t*)ar;
*count = 3;
}
int wmain(int argc, wchar_t* argv[])
{
// names is an array of strings
wchar_t **names = NULL;
int count;
// Squeeze names into the dodgy GetCustomers signature
GetCustomers((wchar_t**)&names,&count);
// Delete each name
for(size_t x = 0; x < count; ++x)
delete[] names[x];
// Delete the array
delete[] names;
return 0;
}
Note that I've matched the cast inside the function with another one in main. This way we keep everything as it should be, except for that pesky GetCustomers signature.
Does this help?