3

I have a program in which I need to work with pointer arrays. My problem is that I do not know how to delete element i from pointer p (p[i]). I will detail the problem below.

I have the structure:

struct CuttingLine
    {
        NxU32 linePoints[150];
        NxU32 lineLength;
        NxVec3 normal;
    };

Then I declare the pointer:

CuttingLine* cuttingLines; 

I initialize the pointer like this:

cuttingLines = (CuttingLine*)malloc(sizeof(CuttingLine) * 10);

And then I add some elements to it (please notice that this is just for demonstration purposes, in my program, line is created and given values):

for(int i=0;i<3;i++)
    cuttingLines[i] = line;

Then I want to go through the pointer again, and delete the three elements, but not free the pointer (I understand that you can delete the pointer by calling free(cuttingLines)). How can I do that? I just want to delete the elements inside it, but not deallocate the memory allocated in the beginning.

leppie
  • 115,091
  • 17
  • 196
  • 297
user2399378
  • 829
  • 2
  • 10
  • 23
  • Delete or erase? What do you want that memory to contain after the operation? – Beta May 22 '13 at 17:14
  • This would be very tedious. For complex list manipulations, use a vector. – ApproachingDarknessFish May 22 '13 at 17:18
  • To *delete* the element (or set it to blank as I understand your question) you'll have to `memset(cuttingLines[i], 0, sizeof(CuttingLine))`. This doesn't deallocate the memory but sets it to `NULL`. – rath May 22 '13 at 17:20
  • I tried to do this: memset(cuttingLines[i], 0, sizeof(CuttingLine)), but I get the erros "no suitable conversion from "CutCloth::CuttingLine" to "void*" exists" – user2399378 May 22 '13 at 20:09

2 Answers2

1

Because cuttingLines is a pointer to CuttingLine, your loop is actually performing a structure copy of line into each of the three positions. There is no need to delete these deep copies. You just have to not use the information anymore when you are done with it, and note that the cuttingLines variable contains unused data. You can then reuse the cuttingLines variable later (filling it with new lines) at your convenience.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • So I can rewrite over them without any problem? – user2399378 May 22 '13 at 17:22
  • @user2399378: That's correct in this case, since your `CuttingLine` structure does not contain any pointers to dynamically allocated memory. – jxh May 22 '13 at 17:23
  • @user2399378: Another caveat, you can rewrite over them without any problem so long as the memory is really not being used by anyone any more. When you asked how to delete the elements without freeing the memory, I assumed this meant that those lines were no longer needed anymore by anyone. – jxh May 22 '13 at 17:47
1

To me it looks like you want to have an array of pointers, and dynamically allocate the elements of the array. In this case you'd want to set the value of the pointer to NULL, which means the pointer doesn't point to anything. Like this:

cuttingLines[i] = NULL;

This means "I have a pointer in my array but it doesn't point to anything".

However if you don't free the memory (by calling free(cuttingLines[i])) you will have a memory leak, so remember to free the memory later in your program. For this you will need to have another pointer somewhere that points to whatever each call to malloc returned.

Just to be pedantic: you can't free a pointer (except in the sense of allocating e.g. sizeof(CuttingLine*) using malloc); you can free memory, so calling free(ptr) frees the memory pointed to by the pointer. Also, you treat cuttingLines like an array of pointers, i.e. pointer of pointers, so its type should be CuttingLine** and you'd declare and allocate it by:

CuttlingLine** cuttingLines;
cuttingLines = (CuttingLine**)malloc(sizeof(CuttingLine*) * 10);

Also, you shouldn't cast the return value of malloc (see here) unless you're writing C++ in which case you shouldn't need to use pointers to pointers in the first place.


If on the other hand you want to have an array of CuttingLines then you're on the right track in the sense that you allocate cuttingLines correctly, and you don't need to free the memory used by individual CuttingLine. However in this case you don't know which elements in the array are valid and which aren't unless you either track the indices in the code or in the elements themselves by e.g. setting lineLength to 0 and checking its value.

Community
  • 1
  • 1
Antti
  • 11,944
  • 2
  • 24
  • 29
  • You are assuming the asker wrote something they didn't intend to write. As the question is currently written, your answer doesn't apply. There is nothing wrong with creating an array of 3 structures as the asker has done. – jxh May 22 '13 at 17:32
  • You are right, the second situation is the one which applies for me, I did just that, I have a variable which keeps track of the number of elements in cuttingLines. Thank you very much for your answer, I'm really new with pointers, and also with c++ for the matter, and I haven't quite figured them out completely yet . I already solved this problem like I said, by keeping track of the number of elements in cuttingLines, but for further operations which might require arrays of complex elements, or even simple arrays, I think I am going to use vectors. They seem relatively simple to deal with. – user2399378 May 23 '13 at 19:51