I had one question.
I developing server in ASIO and packets are in pointed char.
When i create new char (ex. char * buffer = new char[128];) i must clean it manually to nulls.
By:
for(int i =0;i<128;i++)
{
buffer[i] = 0x00;
}
I doing something wrong, that char isn't clear ?
You do not have to loop over an array of un-initialized values. You can dynamically instantiate array of zeros like this:
char * buffer = new char[128](); // all elements set to 0
^^
There are two types of ways of calling the new operator in C++ - default initialised and zero initialised.
To default initialise (which will leave the value undefined) call:
int * i = new int;
It is then undefined behavoir to read or use this value until its been set.
To zeroinitialise (which will set to 0) use:
int * i = new int();
This also works with arrays:
int * i = new int[4]; // ints are not initialised, you must write to them before reading them
int * i = new int[4](); // ints all zero initialised
There's some more info here
Allocated memory will not be clear, it will contain random stuff instead. That's how memory allocation works. You have to either run a for-loop or use memset to clear it manually.
You also can use calloc. It initializes each elem to 0 automaticaly.
e.g:
char* buffer = (char *) calloc (128, sizeof (char))
First param is number of blocks to be allocated. Second is size of block.
This function returns void* so you have to convert its value to (char *)
If you use calloc (or malloc or any "pure c" allocation functions) you'd better use free function to deallocate memory instead of delete.
Related
I've been trying to give an array its size through a variable, but it's not working because "must have a constant value".
int processes[] = { 1, 2, 3 };
int n = sizeof processes / sizeof processes[0];
...
findavgTime(processes, n);
-------------------------------------------------
void findavgTime(int processes[], int n, int bt[])
{
int wt[n], tat[n]; //These two vars are giving me the error
}
Am I missing something?
As you've seen, you can declare an array with a non-constant size like this. You could, however allocate it dynamically using new:
int* wt = new int[n];
int* tat = new int[n];
Just don't forget that you need to delete[] these arrays when you're done.
You can allocate it on the heap like how Mureinik said, but you can also allocate it on the stack (as you were trying to do) with alloca() like this:
int* wt = (int*)alloca(n * sizeof(int));
int* tat = (int*)alloca(n * sizeof(int));
free() should not be called as it is allocated on the stack, not the heap.
Some say using alloca() is bad practice because if the call causes a stack overflow, program behavior is undefined. This shouldn't be a problem as long as the array isn't too long.
Im just wondering ... read about malloc and static allocation. It is obvious that static way is faster. But how about this: instead of doing:
int *s = new int[100];
I would write:
int s[100];
and then use:
std::fill_n(s, 100, 0);
will it be faster too? I mean, I have 2 operations, than just one:
int s[100]; and std::fill_n(s, 100, 0); instead of just int *s = new int[100];
These two expressions are not equivalent:
The first one allocates an array from dynamic store (also known as "the heap"),
The second one allocates an array in the automatic store (also known as "the stack").
The first expression does not value-initialize the array
The second expression fills the array with zeros explicitly
Generally speaking, stack operations are faster, because they are implemented in hardware: essentially, the allocation portion is free. The call of new[] and delete[], on the other hand, are also heavily optimized, so you would see very little difference in most situations.
If you wish to initialize the new array with zeros, you need to put parentheses after the array size, like this:
int *s = new int[100]();
// ^^
How do I do a memset for a pointer to an array?
int (*p)[2];
p=(int(*))malloc(sizeof(*p)*100);
memset(p,0,sizeof(*p)*100);
Is this allocation an correct?
you can use calloc.
calloc will replace both malloc and memset.
p = calloc(100, sizeof (*p));
I'll summarize a lot of answers (although I've ignored some of the stylistic variants in favor of my own preferences).
In C:
How to use malloc:
int (*p)[2] = malloc(100 * sizeof(*p));
How to use memset:
memset(p, 0, 100 * sizeof(*p));
How to do both in one statement:
int (*p)[2] = calloc(100, sizeof(*p));
In C++, the same is possible except that you need to cast the results of malloc and calloc: static_cast<int(*)[2]>(std::malloc(100 * sizeof(*p)).
However, C++ provides alternative ways to allocate this:
int (*p)[2] = new int[100][2](); // like calloc.
delete[] p; // *not* delete p
C++ also provides vector, which is usually nice, but unfortunately you cannot create a vector of C-style arrays. In C++03 you can workaround like this:
struct my_array {
int data[2];
};
std::vector<my_array> p(100);
// no need to free/delete anything
I don't think that zeros the elements, although I might be wrong. If I'm right, then to zero you need:
my_array initvalue = {0};
std::vector<my_array> p(100, initvalue);
another way to represent 2 ints:
std::vector<std::pair<int,int> > p(100);
If you can use Boost:
std::vector<boost::array<int, 2> > p(100);
In C++11:
std::vector<std::array<int, 2>> p(100);
I've listed these in increasing order of how good they usually are, so use the last one that isn't blocked by whatever constraints you're working under. For example, if you expect to take a pointer to the first element of one of the inner arrays-of-2-int, and increment it to get a pointer to the second, then std::pair is out because it doesn't guarantee that works.
The elegant way:
typedef int int_arr_2[2];
int_arr_2* p;
p = malloc(sizeof(int_arr_2)*100);
memset(p,0,sizeof(int_arr_2)*100);
The best way:
typedef int int_arr_2[2];
int_arr_2* p;
p = calloc(100, sizeof(int_arr_2));
calloc, unlike malloc, guarantees that all bytes are set to zero.
The memset() line is proper.
For C you don't need malloc casting.
In C++ if you still want to do this, the type cast should be as:
p = (int(*)[2]) malloc(sizeof(*p)*100); // or `static_cast<...>
// ^^^^^^^^^
But I would suggest to change your approach for using std::vector instead. Cleaner, better and "semi-automatic":
std::vector<int*> vi(100); // or std::vector vi(100, nullptr);
Another way with raw pointers is to use new[]:
int **p = new[100](); // allocates and sets to 0
But you have to manage this memory later on by deallocating with delete[]
In C (not C++) you would just do
int (*p)[2] = malloc(sizeof(*p)*100);
memset(*p,0,sizeof(*p)*100);
that is, variables can be initialized with expressions and malloc doesn't need (and should not have) a cast. Then *p is an "lvalue" of your array type that decays to a pointer when passed to memset.
The function somefunction() takes a triple pointer as an argument.
int somefunction(tchar ***returnErrors);
How to allocate memory for the returnErrors parameter?
At a guess . . .
You can think of returnErrors as a pointer to an array of strings.
The first * imples pointer to array
of tchar (or a single string of
tchars)
The second * imples a pointer to an
array of strings.
The last * is so you can change
returnErrors and pass back the new
memory.
To delare memory for this (silly example, allocating memory inside SomeFunction)
tchar ** errors;
// Oops it appears I need to pass back two error strings (+ 1 for null on end, so we know there are no more - thanks tlholaday)
errors = malloc(sizeof(tchar*) * 3);
// the first string has length 20 (+ 1 for null terminator)
errors[0] = malloc(sizeof(tchar) * 21);
// the second string has length 30 (+ 1 for null terminator)
errors[1] = malloc(sizeof(tchar) * 31);
// ensure the last is null
errors[2] = 0;
*returnErrors = errors;
NB: The calling function needs to know that SomeFunction has allocated memory and needs to free it.
Are you implementing somefunction or calling somefunction?
If you are calling somefunction, it is likely that somefunction will be allocating the memory, so all you need to do is pass it a safe place to scribble and clean up afterwards.
tchar **theErrors = 0; // a vector of tchar vectors.
somefunction(&theErrors);
if (theErrors) {
// use the error values
// free the memory somehow - this is for a null-terminated convention
tchar **victim = theErrors;
while (*victim) delete[](*victim++);
delete[] theErrors;
}
Note: I'm using 0 and delete[] instead of NULL and free because the tag says c++.
It depends on what "somefunction" is expecting. You have to investigate on this !
It may be expecting a pointer to a fixed-size array of dimension 2, or a regular array of dimension 3, or ???
In the cases i mentionned, code could look like
tchar errors[SIZE1][SIZE2];
somefunction( &errors );
or
tchar errors[SIZE1][SIZE2][SIZE3];
somefunction( errors );
Does anyone know how to allocate the
memory for the returnErrors parameter?
The question is too generic and cannot be answered in the general case. Following is just an example of a possible code snippet that calls it.
tchar foo;
tchar * p_foo = &foo;
tchar ** pp_foo = &p_foo;
tchar *** ppp_foo = &pp_foo;
somefunction(ppp_foo);
Just a comment: I would consider your function signature unsafe and thus a code smell even if it had one star less.
Also, note:
A pointer is never an array. It is a
variable which contains the value of
a memory address, or NULL.
The address that a pointer contains
doesn't always correspond to the
starting address of an array. int **
p is not always refering to the
starting address of an int[][].
A pointer whose value contains the
starting address of an array is not
the best way to pass this array as a
function parameter. Instead, a reference to the array type can be used.
An array is usually not the best way to contain a set of related values in C++. std::vector and other STL containers should be considered. (However your question has two languages, C and C++, as tags; of course this only applies to the latter possibility. Why the two tags?)
There are two use cases for a funciton like your someFunction() that I would use.
For initialization:
{
tchar **returnErrors;
initErrors(tchar &returnErrors);
/* now returnErrors has a place in memory*/
}
int initErrors(tchar ***returnErrors)
{
*returnErrors = malloc(sizeof(tchar *) * SIZE1)
for (i = 0; i < NUM_ELEMENTS; i++)
(*returnErrors)[i] = malloc(sizeof(tchar) * SIZE2);
/*add checks for malloc failures*/
}
Array passing to a function:
{
returnErrors[SIZE1][SIZE2][SIZE3];
someFunciton(returnErrors);
}
int someFunciton(tchar ***returnErrors)
{
/*assuming that this is a valid index*/
tchar x = returnErrors[1][1][1];
/*return errors is used as a triple array*/
}
The triple pointer does not make any sense if you don't already have a construct of that type. I would rather recommend using a class - or at least a standard container. But if you must know, it's as simple as
tchar ***pointer = (tchar***) malloc(sizeof(tchar**) * amount);
I'd tend agree with tlholaday's guess, with the modification that the function likely returns the number of errors it allocates.
tchar **theErrors = 0; // a vector of tchar vectors.
int nErrors = somefunction(&theErrors);
if (nErrors > 0) {
for (int i = 0; i < nErrors; ++i)
{
printf(theErrors[i]);
free(theErrors[i]);
}
free(theErrors);
}
Note that whether you use free or delete[] will depend on how the memory was allocated in the first place.
I am declaring an array of void pointers. Each of which points to a value of arbitary type.
void **values; // Array of void pointers to each value of arbitary type
Initializing values as follows:
values = (void**)calloc(3,sizeof(void*));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;
//Trying to Clear the memory allocated
free(*values);
//Error: *** glibc detected *** simpleSQL: free(): invalid pointer: 0x080611b4
//Core dumped
delete[] values*;
//warning: deleting 'void*' is undefined
//Similar Error.
Now how do I free/delete the memory allocated for values ( the array of void pointers)?
I suspect the issue is with the way that you allocated values: values = (void*)calloc(3,sizeof(void)). That should be sizeof(void *) rather than just sizeof(void).
sizeof(void) may be zero or something else that makes no sense, so you're not really allocating any memory to begin with... it's just dumb luck that the assignments work, and then the error pops up when you try to deallocate the memory.
EDIT: You're also asking for trouble by alternating between C++-style new/delete with C-style malloc/free. It is okay to use them both as long as you don't delete something you malloc'ed or free something you new'ed, but you're going to mix them up in your head if you go like this.
You have 3 things that are dynamically allocated that need to be freed in 2 different ways:
delete reinterpret_cast<int*>( values[0]);
delete reinterpret_cast<float*>( values[1]);
free( values); // I'm not sure why this would have failed in your example,
// but it would have leaked the 2 items that you allocated
// with new
Note that since str is not dynamically allocated it should not (actually cannot) be freed.
A couple of notes:
I'm assuming that the sizeof(void)
was meant to be sizeof(void*)
since what you have won't compile
I'm not going to say anything about
your seemingly random casting except
that it looks like code that ready
for disaster in general
This is the perfect situation for the boost::any class
Also you may want to consider using a vector rather than allocating your own memory.
std::vector<boost::any> data;
boost::any i1 = 1; // add integer
data.push_back(i1);
boost::any f1 = 1.0; // add double
data.push_back(f1);
data.push_back("PLOP"); // add a char *
std:: cout << boost::any_cast<int>(data[0]) + boost::any_cast<double>(data[1])
<< std::endl;
Going back to your original code the main problem was:
values = (void*)calloc(3,sizeof(void));
// This should have been
void** values = (void**)calloc(3,sizeof(void*));
// Freeing the members needs care as you need to cast them
// back to the correct type before you release the memory.
// now you can free the array with
free(values);
Also note: Though it is not illegal to use both new/delete and calloc/free in the same piece of code it is frowned upon. Mainly because it is easy to get things mixed up and that could potentially be fatal.
You're mixing new and *alloc(). That's a no-no, and can lead to undefined results.
I'm not sure why you are using new if you're doing things in C (referencing the tag here).
I would malloc the individual pieces of the array I need and then free them when I'm done I suppose. You can't free something you didn't first malloc. You also can't delete a void pointer.
Note that you're also not deleting values[0] and values[1] which is a memory leak, Yet by your design you can't free values[2] since its a pointer into you .data section.
You'd have to keep track of how many void* were originally calloc'd, and iterate over them, free-ing each one, then free the original values variable.
darn formatting... (the preview is working fine).
int ct = 3;
values = (void*)calloc(ct,sizeof(void));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;
for ( int i = 0; i < ct; i++ ) [
delete( values[i] );
}
free( values );