I came up with this as a quick solution to a debugging problem - I have the pointer variable and its type, I know it points to an array of objects allocated on the heap, but I don't know how many. So I wrote this function to look at the cookie that stores the number of bytes when memory is allocated on the heap.
template< typename T >
int num_allocated_items( T *p )
{
return *((int*)p-4)/sizeof(T);
}
//test
#include <iostream>
int main( int argc, char *argv[] )
{
using std::cout; using std::endl;
typedef long double testtype;
testtype *p = new testtype[ 45 ];
//prints 45
std::cout<<"num allocated = "<<num_allocated_items<testtype>(p)<<std::endl;
delete[] p;
return 0;
}
I'd like to know just how portable this code is.
It is not even remotely portable.
An implementation can perform heap bookkeeping however it wants and there is absolutely no way to portably get the size of a heap allocation unless you keep track of it yourself (which is what you should be doing).
You can globally overload new/delete operators on array, and put the size into the memory area. You get a portable solution.
The below code shows how:
void * operator new [] (size_t size)
{
void* p = malloc(size+sizeof(int));
*(int*)p = size;
return (void*)((int*)p+1);
}
void operator delete [] (void * p)
{
p = (void*)((int*)p-1);
free(p);
}
template<typename T>
int get_array_size(T* p)
{
return *((int*)p-1)/sizeof(T);
}
int main(int argc, char* argv[])
{
int* a = new int[200];
printf("size of a is %d.\n", get_array_size(a));
delete[] a;
return 0;
}
Result:
size of a is 200.
Not portable. But why not use std::vector? Then you can ask it directly how many elements it contains, and you won't need to worry about memory management and exception safety.
Related
my question can be briefly shown as the following example.
void func(int n){
char *p = (char*)malloc(n);
// some codes
memset(p,0,sizeof(name));
// free(p); // Commenting this line represents that I forget to release the allocated memory.
}
int main(){
// some codes
for (int i; i < Nl; i++){
func(100);
// How can I release the allocated memory of p outside of the func?
}
}
I whish to release the allocated memory, which is allocated in a function, outside of this function.
Thank you.
The pointer in question is not returned from the function in any way, so if you don't free it in the function then the memory is leaked. You would need to modify the function to either assign the pointer to a global, return it from the function, or assign it to a dereferenced pointer passed to the function.
If your goal is to find and fix memory leaks in your program, there are tools such as valgrind which can help you with that.
To solve the problem it's better to use std::unique_ptr. If you use smart pointer it will be released whenever it's not required anymore.
Foe example :
void my_func()
{
std::unique_ptr<int> valuePtr(new int(15));
int x = 45;
// ...
if (x == 45)
return; // no memory leak anymore!
// ...
}
You can check the link to study more :
https://en.cppreference.com/book/intro/smart_pointers
Two solutions in C
a) use VLA
void foo(int n) {
char p[n];
// use p
// no need to free, p automatically releases its memory
}
b) return the pointer to the caller
char *foo(int n) {
char *p = malloc(n);
// use p
return p;
}
int main(void) {
char *bar = foo(100);
free(bar);
}
If I understand you correctly, you are struggling with the basic concept of memory management.
Looking at your code you are malloc, which is a core C memory management aspect, although you tagged the question as C and C++. I can go into depth on why there ain't a thing like C/C++, though it's better explained here: https://cor3ntin.github.io/posts/c/
One of the elements C and C++ programmers disagree is the use of malloc, which is standard in C and and only used in exceptional cases in C++.
If we look from a C++ standpoint, I'd argue you should be learning it with a recent version. Here the answer is simple: use std::make_unique:
auto p = std::make_unique<char[]>(n);
Or in this case as you are trying to do something with strings, just use std::string. Trust me, doing so will prevent a lot of grief. Let me also remark that you often don't need memory allocations, more about that can be found here: https://stackoverflow.com/a/53898150/2466431
If you however ain't programming C++, you can use malloc. Here it is important to understand that every pointer returned by malloc ends up as an argument for free. (Exceptions on this ain't for beginners)
After you call free, you can't use what the pointer points to, not the value stored in the pointer. Calling free twice for the same pointer is also an issue.
Hence, unlike in the C++ code where the memory gets freed when no longer used. You need to keep detailed attention for this and call free.
In your function, uncommenting the free is the correct solution.
If you have the intention to let the data outlive the function call, you should be returning the pointer to the caller, this is than responsible for the ownership:
char * func(int n){
char *p = (char*)malloc(n);
// some codes
memset(p,0,sizeof(name));
return p;
}
int main(){
// some codes
for (int i; i < Nl; i++){
char *s = func(100);
free(s);
}
}
Let me show the same with the previously mentioned C++:
#include <memory>
std::unique_ptr<char[]> func(int n){
auto p = std::make_unique<char[]>(n);
// some codes
return p;
}
int main(){
// some codes
for (int i; i < Nl; i++){
auto s = func(100);
}
}
Or using std::string
#include <string>
std::string func(int n){
auto p = std::string(n, '\0');
// some codes
return p;
}
int main(){
// some codes
for (int i; i < Nl; i++){
auto s = func(100);
}
}
I'm going to write a piece of code (Function) that returns a pointer to an array.
but I don't know how to do that.
The code I wrote is :
int* prime_factor(int temp){
int ctr;
int *ret;
int i = 0;
while (temp != 1){
ctr = 2;
if (temp%ctr != 0){
ctr++;
}
else {
*(ret + i) = ctr;
temp /= ctr;
}
}
return ret;
}
I guess that there's a need to such the thing :
else {
ret = new int[1];
*(ret +i) = ctr;
temp /= ctr;
}
But as you know , implementation of this stuff needs to be deleted the memory that you have allocated , so we have to delete the memory outside of the function , so it going to be nonstandard function.
Indeed, i want to calculate the Prime factors of a number then return them out.
Any idea to do that ? I don't know what should I do to gain the goal.
thank you so much.
I see your question has also the tag C++ so, you could use C++. I don't really know what you mean with without static integer ....
Use vector.
#include <vector>
vector<int> prime_factor(int number)
{
int ctr = 2;
vector<int> factors;
while (number != 1)
{
if (number % ctr != 0)
ctr++;
else
{
factors.push_back(ctr);
number /= ctr;
}
}
return factors;
}
As you will be using the vector with integers it knows how to destroy ("delete") it self.
Example:
int main()
{
for (auto &x : prime_factor(20)) // C++11
{
cout << x << endl;
}
}
Output:
2
2
5
Yes, putting burden of deleting the array on user is not preferable. Here you would be better off using vector instead of plain array.
You can also pass array as an argument(created in the caller so that it would be more intuitive to use delete on that array) to this function.
The line *(ret + i) = ctr; will create a memory violation right away, since your ret pointer has no allocated memory pointing to. You nee do preallocate a memory for it, either statically (array declaration) in the code CALLING this function, and passing it to the function as a parameter, or dynamically (using malloc or similar) and then freeing it in some point. Dynamic allocation can be done either in the function itself or in the calling code. But again, free the memory afterwards.
int *ret;
In your case ret doesn't point to any memory location.You are trying to reference some unallocated memory location which might cause segmentation fault.
Just to show how to return a pointer and free it below is the example:
int *some()
{
int *ret = malloc(sizeof(int));
*ret = 10;
return ret;
}
int main()
{
int *p = some();
printf("%d\n",*p);
free(p);
}
"But as you know , implementation of this stuff needs to be deleted the memory that you have allocated , so we have to delete the memory outside of the function , so it going to be nonstandard function."
To avoid that dilemma c++ has introduced Dynamic memory management support.
Instead of using raw pointers like int* use one appropriate of
std::unique_ptr<int> (to transfer ownership)
std::shared_ptr<int> (to share ownership)
std::weak_ptr<int> (to share ownership, but not count as reference)
std::auto_ptr<int> (to transfer ownership "the old way")
Besides that, it looks like using a std::vector<int> would be much more appropriate, than using a simple int*. The std::vector<int> class also is purposed to release you from getting the dynamic memory management right on your own.
What is the proper way to create an unique_ptr that holds an array that is allocated on the free store? Visual studio 2013 supports this by default, but when I use gcc version 4.8.1 on Ubuntu I get memory leaks and undefined behaviour.
The problem can be reproduced with this code:
#include <memory>
#include <string.h>
using namespace std;
int main()
{
unique_ptr<unsigned char> testData(new unsigned char[16000]());
memset(testData.get(),0x12,0);
return 0;
}
Valgrind will give this output:
==3894== 1 errors in context 1 of 1:
==3894== Mismatched free() / delete / delete []
==3894== at 0x4C2BADC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3894== by 0x400AEF: std::default_delete<unsigned char>::operator()(unsigned char*) const (unique_ptr.h:67)
==3894== by 0x4009D0: std::unique_ptr<unsigned char, std::default_delete<unsigned char> >::~unique_ptr() (unique_ptr.h:184)
==3894== by 0x4007A9: main (test.cpp:19)
==3894== Address 0x5a1a040 is 0 bytes inside a block of size 16,000 alloc'd
==3894== at 0x4C2AFE7: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3894== by 0x40075F: main (test.cpp:15)
Using the T[] specialisation:
std::unique_ptr<unsigned char[]> testData(new unsigned char[16000]());
Note that, in an ideal world, you would not have to explicitly use new to instantiate a unique_ptr, avoiding a potential exception safety pitfall. To this end, C++14 provides you with the std::make_unique function template. See this excellent GOTW for more details. The syntax is:
auto testData = std::make_unique<unsigned char[]>(16000);
Use the array version :
auto testData = std::unique_ptr<unsigned char[]>{ new unsigned char[16000] };
Or with c++14, a better form ( VS2013 already has it ):
auto testData = std::make_unique<unsigned char[]>( 16000 );
A most likely better way would be to use std::vector<unsigned char> instead
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<unsigned char> testData(0x12, 0); // replaces your memset
// bla
}
The advantage is that this is much less error-prone and gives you access to all kinds of features such as easy iteration, insertion, automatic reallocation when capacity has been reached.
There is one caveat: if you are moving your data around a lot, a std::vector costs a little more because it keeps track of the size and capacity as well, rather than only the beginning of the data.
Note: your memset doesn't do anything because you call it with a zero count argument.
unsigned int size=16000;
std::unique_ptr<unsigned char[], std::default_delete<unsigned char[]>> pData(new unsigned char[size]);
Seems like a goofup, i will explain what i mean
class Object {
private :
static int count;
public :
Object() {
cout << "Object Initialized " << endl;
count++;
}
~Object() {
cout << "Object destroyed " << endl;
}
int print()
{
cout << "Printing" << endl;
return count;
}
};
int Object::count = 0;
int main(int argc,char** argv)
{
// This will create a pointer of Object
unique_ptr<Object> up2 = make_unique<Object>();
up2->print();
// This will create a pointer to array of Objects, The below two are same.
unique_ptr<Object[]> up1 = std::make_unique<Object[]>(30);
Object obj[30];
cout << up1.get()[8].print();
cout << obj[8].print();
// this will create a array of pointers to obj.
unique_ptr<Object*[]> up= std::make_unique<Object*[]>(30);
up.get()[5] = new Object();
unique_ptr<Object> mk = make_unique<Object>(*up.get()[5]);
cout << up.get()[5]->print();
unique_ptr<unique_ptr<Object>[]> up3 = std::make_unique<unique_ptr<Object>[]>(20);
up3.get()[5] = make_unique<Object>();
return 0;
}
Objective of the post is that there are hidden small subtle things you need to understand. Creating array of objects is same as object array of unique_ptr. It will make difference only when you pass it in the argument. Creating array of object pointers of unique_ptr is also not very useful. So only below two you need to use in most scenarios.
unique_ptr<Object> obj;
//and
unique_ptr<unique_ptr<Object>[]>= make_unique<unique_ptr<Object>[]>(20);
Probably something like the following?
using namespace std;
int size = get_size();
int const init_value = 123;
unique_ptr<int[]> p = make_unique<int[]>(size)
fill(p.get(), p.get() + size, init_value);
I can construct data on Line 19 from vvp.at(0) if I know the size of vf.
#include <iostream>
#include <vector>
typedef void* VoidPointer;
typedef std::vector< float > VF;
typedef std::vector< VoidPointer > VVP;
int main(int argc, char** argv)
{
VF vf;
vf.push_back(13.0f);
vf.push_back(14.0f);
vf.push_back(15.0f);
vf.push_back(16.0f);
VVP vvp;
vvp.push_back( (VoidPointer)const_cast<float *>( &(vf.front()) ) );
VF data ( static_cast< float* >( vvp.at(0) ),
static_cast< float* >( vvp.at(0) ) + vf.size() );
std::cout << "data.size() is " << data.size() << std::endl;
for(VF::const_iterator i = data.begin(); i != data.end(); ++i)
{
std::cout << "data contains " << *i << std::endl;
}
return 0;
}
Leaving aside whether this is sensible (the example is contrived) I'd like to know how to cast vvp.at(0) to a std::vector<float> if I didn't know the size of vf. I'm thinking along the lines of something like:
std::vector<float> data( *static_cast< std::vector<float>* >( vvp.at(0) ) );
But that causes the program to termintate with std::bad_alloc, I don't mind copying if need be.
That is not a cast from vvp.at(0) to a vector, it's a copy of an array of floats into a new vector. And you can't copy it without knowing the length. You only saved a pointer to the first element, so the information was lost.
You could make std::vector<std::pair<VoidPointer, size_t> > VVP and save both &vf.front() and vf.size() (or start and end pointers, if you prefer).
You could make std::vector<VF *> and store pointers to vectors (i.e. vvp.push_back(&vf)) and now there's no casting at all.
Edit: In case you didn't realize: The pointer &vf is unrelated to &vf.front(). vf is a structure which contains the pointer &vf.front() (or a way to get it). There's no information in just the address &vf.front() to let you find &vf.
The only thing I can think of is extremely non-portable (and equally crazy). Each vector allocates a contiguous array of memory. Any allocation function has to keep track of how many bytes have been allocated, so that it can de-allocate them given only the beginning of the allocation's address.
AFAIK, the C++ standard does not specify how this book keeping is done and therefore, this up to each compiler. One method is to write a count before the actual allocation address - I believe this is what the Visual C++ compiler does. (Eg. if allocating at 0x104, a 32-bit count could be stored at 0x100). Again, you will have to know how your specific compiler does this book keeping.
Anyway, the point is, once you do, a little pointer arithmetic and de-referencing could theoretically look up the allocated size (I'm of course assuming you're still using a vector with a default allocator here), and figure out how many floats were actually allocated using only a void pointer.
Here's an example that works in Visual Studio in 32-bit debug mode:
#include <iostream>
#include <vector>
size_t bytes_allocated( void* p )
{
#ifndef _DEBUG
#error Doesn't work
#endif // _DEBUG
size_t const offset = 12;
size_t const counter_size = 4;
size_t const total_offset = offset + counter_size;
void* counter_address = ((char*)p)-total_offset;
size_t* count = reinterpret_cast<size_t*>(counter_address);
return *count;
}
int main(int argc, char* argv[])
{
typedef float test_type;
std::vector<test_type> v;
v.push_back(23);
v.push_back(23);
v.push_back(23);
size_t count = bytes_allocated(&v[0]);
std::cout<<count<<" bytes allocated\n";
std::cout<<count/sizeof(test_type)<<" items allocated\n";
return 0;
}
The output is:
12 bytes allocated
3 items allocated
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.)