Correct syntax to use new for char* array - c++

I have the following
typedef struct
{
int titleCount;
char** titles;
} myStruct;
And then
...
struct1->titleCount = 2;
struct1->titles = (char**) malloc(sizeof(char *) * (str->titleCount + 1));
...
What would be the correct syntax for using new instead of malloc?

in the example, titles points to an array of pointers to char or most probably actually strings. So I would expect something like:
titles = new char*[str->titleCount]; // or maybe keep the +1
followed by a loop to allocate the individual strings and put pointers to them into the array pointed-to by titles.

If you are porting from C to C++, the better solution would be:
std::vector<std::string> myTitles;
The entire struct is unnecessary.

First of all your code of allocating memory is invalid because you may not write
struct1->titleCount
unless somewhere you wrote
struct struct1 *struct1 = malloc( sizeof( struct struct1 ) );
However from the code you presented it seems that you need to allocate
str->titleCount + 1
elements of type char *
So the corresponding code will look as
str->titleCount = 2;
str->titles = new char * [str->titleCount + 1];
Next time please show a code snippet that could be compiled. From you code it is not clear what is struct1 and str. You only confuse others.

Related

Pointer help: dereferencing a pointer to a struct accessing data within it

I'm having some trouble wrapping my head around how a certain line of code works. For some reason it's just not clicking. This line of code is used generally with abstracting file handles in unix domain sockets.
Context:
typedef struct myStruct {
char charArray[10];
} myStruct;
myStruct myStructure;
myStruct *ptrToStruct = &myStructure;
/* This should change myStructure.charAarray[0] to equal a */
*(ptrToStruct.charArray) = 'a';
I understand that an array is essentially a pointer that is pointing to the first index in the array but the pointer has no data (charArray).
The reason this is so hard for me to understand is because the ptrToStruct is trying to access the pointer's data member charArray but the pointer has no data member charArray and then it's dereferencing it.
Is this sort of like (*ptrToStruct).(*charArray) = 'a'? But the dereferencing operator is being factored out? I apologize for being at all unclear.
UPDATE: The question has been answered. I was misreading code, the code was actually *(myStructure.charArray) and that's how it was altering the first index of the array. I should have also figured this out because as Sid explained pointers do not have the . operator.
ptrToStruct isn't a struct, so
ptrToStruct.charArray
should be
(*ptrToStruct).charArray
or
ptrToStruct->charArray
Then, yes, you can set the character using
*( ptrToStruct->charArray ) = 'a';
or
( ptrToStruct->charArray )[0] = 'a';
This is no different than
char charArray[10];
*charArray = 'a';
and
char charArray[10];
charArray[0] = 'a';

C - passing an array by reference - only first element set

I have a function which should modify an array (of floats) in the original parent function. I am using the following code:
void sortFunction(Word**words, int wordCount){ //to sure if two * are correct (pointer to an array..?)
int i = 0;
for(i=0;i<wordCount-1;i++){
Word first = *words[i]; //values fine
Word second = *words[i+1]; //weird values, causes segfault
if(first.data[0] > second.data[0]){
//do stuff
}
}
}
int main(int argc, char ** argv){
Word* words = NULL;
int wordsCount = ...
//filling the array in a loop and using realloc for memory allocation
//Here, the array is filled correctly (verified)
sortFunction(&words, wordsCount);
}
Where Word is a typedef struct and Word.data is the (dynamic) float array. When checking in the parent function, the array is allocated and the values set correctly.
I have tried with about 10 elements in the array, but always only the first ([0]) element is fine in the sortFunction(), second and all others are messed up. I also have an int propery in the struct, and when I try to print it for the second element, I get something over 1 billion.
I assume I am not passing the array correctly - I use the following code (just a sample) to pass regular variables, so I tried to modify it for an array, but apparently, not correctly. What is the right way to do this for an array?
void foo(int*var){
*var=8;
}
int main(){
int var = 5;
changeVar(&var);
}
Thanks in advance for any tips!
Postfix [] has higher precedence than unary *, so *words[i] is parsed as *(words[i]), which isn't what you want.
You need to dereference the words pointer before applying the subscript, so you need to explicitly group the * operator with words using parentheses:
Word first = (*words)[i];
Word second = (*words)[i + 1];
First, you do not need to pass **, just one is enough, because you will be passing the address of your array anyway:
void sortFunction(Word* words, int wordCount)
and call it as:
sortFunction(words, wordsCount);
Second, the Undefined behavior originates in the following statement:
Word first = *words[i]; Word second = *words[i+1];
It should have been (*words)[i] but still, you are copying structs, so your dynamic data array is not copied correctly. avoid this useless copy, and use this instead, AFTER changing the protoype of sortFunction:
Word* first = &words[i];
Word* second = &words[i+1];
if(first->data[0] > second->data[0])
p.s: This does not guarantee that the rest of your code is correct, just comments of the parts you showed of the code.

Casting SomeType** to SomeType*[] and vice versa

I really need to this specifically as I am using SWIG and need to make a cast to match the function definition.
The function definition accepts
SomeType const * const variable_name[]
Also, another question would be-
How to allocate memory to
SomeType * variable[] = <??? using new or malloc >
for x entries?
Edit:
I have searched quite a lot, but I keep stumbling into post which allocate memory to SomeType** using new SomeType*[x] i.e.
SomeType** variable = new SomeType*[x];
Can you please tell me a way to do this?
The function wants an array of pointers.
The statement:
SomeType * variable[];
Is not valid syntax.
You will need:
SomeType * * variable;
Declares a pointer to a pointer of SomeType.
You will need to perform memory allocation in two steps.
First, allocate the array of pointers:
variable = new SomeType * [/* some quantity */];
Remember, the above statement only allocates room for the pointers. The memory contents is still not initialized.
Secondly, allocate pointers to the objects.
for (unsigned int i = 0; i < some_quantity; ++i)
{
variable[i] = new SomeType;
}
When deleting, delete the contents of the array before the array:
for (unsigned int i = 0; i < some_quantity; ++i)
{
delete variable[i];
}
delete[] variable;
The function definition accepts
SomeType const * const variable_name[]
I'm no expert in C++, but if the declaration of arrays in function parameters is the same as in C then this is a synonym for the following type:
SomeType const * const * variable_name
That is, an array in a function parameter is really a pointer. Your book should have explained this early on.
I have searched quite a lot, but I keep stumbling into post which allocate memory to SomeType** using new SomeType*[x] i.e.
SomeType** variable = new SomeType*[x];
Can you please tell me a way to do this?
You could indeed allocate a SomeType const * const * using similar code to that, so you've answered your own question. I assume you could also use an std::vector<SomeType const * const> like so:
std::vector<SomeType const * const> *foo = new std::vector<SomeType const * const>();
/* XXX: Add some items to the vector */
SomeType const * const *bar = &foo[0];
This would be useful if you're not sure how many items foo should contain, and you expect it to grow.
I don't understand why people don't read books anymore. It's the fastest and cheapest (if you consider the cost of man hours) way to learn correctly from a reputable figure.

Pointer to array of character arrays

Okay, this one has me stumped. I am trying to pass an array of character arrays into my class's constructor. The class has a private attribute which stores a pointer to the array of character arrays. The class may then process the array via the pointer.
Below is some code that demonstrates the desired functionality. But, it won't compile. How do I fix this code so it works?
using namespace std;
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char * inArray[][MAX_STRING]) : input(inArray){};
private:
char * input[MAX_LINES][MAX_STRING];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
Alphabetizer theAlaphBet(charArray);
return 0;
}
If you're insisting on using C-compatible character pointers, I think you'll have the best luck using a char ** as the type for input. This is more of the usual way to do this (in C at least), and it has the added benefit of not forcing you to define a maximum string size.
As others have pointed out, you can take advantage of std::string instead, which may be a better choice overall.
I'm guessing it's that you're not passing a pointer to char[][], you're passing a char[][].
Also, you should be using std::string instead of char arrays.
std::string will be the most appropriate here! It handles strings and character arrays well enough!
There are few errors in the code. I suppose you are trying to refer to the charArray in the main function from inside the Alphabetizer object. If that is the case the declaration
char * input[MAX_LINES][MAX_STRING];
is wrong because the above declaration makes input an array of MAX_LINE of ( array of MAX_STRING of (char*)). In summary input is an array not a pointer to array of whatever. If you had intended it to be a pointer - which is what rest of your code hints to me - then you have to do the following,
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char ((*ar)[MAX_LINES])[MAX_STRING]) : m_ar(ar){};
private:
char ((*m_ar)[10])[80];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
char ((*ar)[MAX_LINES])[MAX_STRING] = &charArray;
Alphabetizer theAlaphBet(&charArray);
return 0;
}
Moreover doing,
input(inArray)
is wrong, as it is equivalent to doing the following,
char a[1] = {'a'};
char b[1] = {'p'};
a = b;
assigning an array to another does not copy one over another. You have to do explicit memcpy. (This semantics is not meaningful in c or c++)
It's difficult to tell without seeing the compile errors, but I think the problem might be this line:
Alphabetizer theAlaphBet(charArray);
You are passing the array directly rather than it's address. It should read:
Alphabetizer theAlaphBet( &charArray );
However I think you may be overcomplicating things. You might be better off using a reference rather than a pointer:
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char & inArray[][MAX_STRING]) : input(inArray){};
private:
char & input[MAX_LINES][MAX_STRING];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
Alphabetizer theAlaphBet(charArray);
return 0;
}
You might also want to look into using std::string instead as this may help to simplify your code.

Dynamically allocate C struct?

I want to dynamically allocate a C struct:
typedef struct {
short *offset;
char *values;
} swc;
Both 'offset' and 'values' are supposed to be arrays, but their size is unknown until runtime.
How can I dynamically allocate memory for my struct and the struct's arrays?
swc *a = (swc*)malloc(sizeof(swc));
a->offset = (short*)malloc(sizeof(short)*n);
a->values = (char*)malloc(sizeof(char)*n);
Where n = the number of items in each array and a is the address of the newly allocated data structure. Don't forget to free() offsets and values before free()'ing a.
In C:
swc *s = malloc(sizeof *s); // assuming you're creating a single instance of swc
if (s)
{
s->offset = malloc(sizeof *(s->offset) * number_of_offset_elements);
s->values = malloc(sizeof *(s->values) * number_of_value_elements);
}
In C++:
try
{
swc *s = new swc;
s->offset = new short[number_of_offset_elements];
s->values = new char[number_of_value_elements];
}
catch(...)
{
...
}
Note that in C++, you might be better off using vectors as opposed to dynamically allocated buffers:
struct swc
{
std::vector<short> offset;
std::vector<char> values;
};
swc *a = new swc;
Question: is values supposed to be an array of individual characters or an array of strings? That would change things a bit.
EDIT
The more I think about it, the less satisfied I am with the C++ answer; the right way to do this sort of thing in C++ (assuming you need dynamically allocated buffers as opposed to vectors, which you probably don't) is to perform the memory allocation for offset and values as part of a constructor within the struct type, and have a destructor deallocate those elements when the struct instance is destroyed (either by a delete or by going out of scope).
struct swc
{
swc(size_t numOffset = SOME_DEFAULT_VALUE,
size_t numValues = SOME_OTHER_DEFAULT_VALUE)
{
m_offset = new short[numOffset];
m_values = new char[numValues];
}
~swc()
{
delete[] m_offset;
delete[] m_values;
}
short *m_offset;
char *m_values;
};
void foo(void)
{
swc *a = new swc(10,20); // m_offset and m_values allocated as
// part of the constructor
swc b; // uses default sizes for m_offset and m_values
...
a->m_offset[0] = 1;
a->m_values[0] = 'a';
b.m_offset[0] = 2;
b.m_values[0] = 'b';
...
delete a; // handles freeing m_offset and m_values
// b's members are deallocated when it goes out of scope
}
You have to do it seperately. First allocate the struct, then the memory for the arrays.
In C:
swc *pSwc = malloc(sizeof(swc));
pSwc->offset = malloc(sizeof(short)*offsetArrayLength);
pSwc->values = malloc(valuesArrayLength);
In C++, you shouldn't be doing anything like that.
In C:
typedef struct
{
short *offset;
char *values;
} swc;
/// Pre-Condition: None
/// Post-Condition: On failure will return NULL.
/// On Success a valid pointer is returned where
/// offset[0-n) and values[0-n) are legally de-refrancable.
/// Ownership of this memory is returned to the caller who
/// is responsible for destroying it via destroy_swc()
swc *create_swc(unsigned int size)
{
swc *data = (swc*) malloc(sizeof(swc));
if (data)
{
data->offset = (short*)malloc(sizeof(short)*n);
data->values = (char*) malloc(sizeof(char) *n);
}
if ((data != NULL) && (size != 0) && ((data->offset == NULL) || (data->values == NULL)))
{
// Partially created object is dangerous and of no use.
destroy_swc(data);
data = NULL;
}
return data;
}
void destroy_swc(swc* data)
{
free(data->offset);
free(data->values);
free(data);
}
In C++
struct swc
{
std::vector<short> offset;
std::vector<char> values;
swc(unsigned int size)
:offset(size)
,values(size)
{}
};
You will need a function to do this.
Something like (my C/C++ is rusty)
swc* makeStruct(int offsetCount, int valuesCount) {
swc *ans = new swc();
ans->offset = new short[offsetCount];
ans->values = new char[valuesCount];
return ans;
}
myNewStruct = makeStruct(4, 20);
Syntax may be a bit off but that is generally what you are going to need. If you're using C++ then you probably want a class with a constructor taking the 2 args instead of the makeStruct but doing something very similar.
One thing to add to the many correct answers here: you can malloc an over-sized structure to accommodate a variable sized array in the last member.
struct foo {
short* offset;
char values[0]
};
and later
struct *foo foo1 = malloc(sizeof(struct foo)+30); // takes advantage of sizeof(char)==1
to get room for 30 objects in the values array. You would still need to do
foo1->offsets = malloc(30*sizeof(short));
if you want them to use the same size arrays.
I generally wouldn't actually do this (maintenance nightmare if the structure ever needs to expand), but it is a tool in the kit.
[code here in c. You'll need to cast the malloc's (or better use new and RAII idioms) in c++]
swc* a = malloc(sizeof(*a));
a->offset = calloc(n, sizeof(*(a->offset)));
a->values = calloc(n, sizeof(*(a->values)));
You should not cast void* in c... in c++ you must!
Use malloc function or calloc to allocate memory dynamically .
and search it on google to get examples.
The calloc function initializes allocated memory to zero.
Since nobody has mentioned it yet, sometimes it is nice to grab this chunk of memory in one allocation so you only have to call free() on one thing:
swc* AllocSWC(int items)
{
int size = sizeof(swc); // for the struct itself
size += (items * sizeof(short)); // for the array of shorts
size += (items * sizeof(char)); // for the array of chars
swc* p = (swc*)malloc(size);
memset(p, 0, size);
p->offset = (short*)((char*)swc + sizeof(swc)); // array of shorts begins immediately after the struct
p->values = (char*)((char*)swc + sizeof(swc) + items * sizeof(short)); // array of chars begins immediately after the array of shorts
return p;
}
Of course this is a bit more difficult to read and maintain (especially if you dynamically resize the arrays after it is first allocated). Just an alternative method I've seen used in a number of places.
Most of the answers are correct. I would like to add something that you haven't explicitly asked but might also be important.
C / C++ arrays don't store their own size in memory. Thus, unless you want offset and values to have compile-time defined values (and, in that case, it's better to use fixed-size arrays), you might want to store the sizes of both arrays in the struct.
typedef struct tagswc {
short *offset;
char *values;
// EDIT: Changed int to size_t, thanks Chris Lutz!
size_t offset_count;
size_t values_count; // You don't need this one if values is a C string.
} swc;
DISCLAIMER: I might be wrong. For example, if all offsets of all swc instances have the same size, it would be better to store offset_count as a global member, not as a member of the struct. The same can be said about values and values_count. Also, if values is a C string, you don't need to store its size, but beware of Schlemiel the painter-like problems.
You want to use malloc to allocate the memory, and probably also sizeof() to allocate the correct amount of space.
Something like:
structVariable = (*swc) malloc(sizeof(swc));
Should do the trick.
In addition to the above, I would like to add freeing up the allocated memory as below.,
typedef struct {
short *offset;
char *values;
} swc;
swc* createStructure(int Count1, int Count2) {
swc *s1 = new swc();
s1->offset = new short[Count1];
s1->values = new char[Count2];
return s1;
}
int _tmain(int argc, _TCHAR* argv[])
{
swc *mystruct;
mystruct = createStructure(11, 11);
delete[] mystruct->offset;
delete[] mystruct->values;
delete mystruct;
return 0;
}
**If** you will not be resizing the arrays, then you can get away with a single call to malloc().
swc *new_swc (int m, int n) {
swc *p;
p = malloc (sizeof (*p) + m * sizeof (p->offset[0]) + n * sizeof (p->values[0]);
p->offset = (short *) &p[1];
p->values = (char *) &p->offset[m];
return p;
}
You can then free it with a single call to free().
(In general, there are alignment considerations to take into account, but for an array of shorts followed by an array of chars, you will be fine.)