0

I'm new to C, so the answer might be obvious but I just can't get my head around it.

I'm trying to create C++ vector kind of structure in C. I use Windows EnumWindows function to loop through all the windows. In the callback function I create new instance of windowHandle -structure for each window. For some reason however it doesn't seem to create new instance but rather just overwrites the old one. Or maybe it creates new instance, but when I give value to attribute windowHandle->title, it applies that change to every instance of windowHandle?

Callback function:

BOOL CALLBACK delegate(HWND wnd, LPARAM param){
if (filter(wnd)){ //<- just to make sure it's kind of window that we want.
            char windowName[256] = {};
            GetWindowText(wnd, windowName, sizeof(windowName));
            windowHandle *handle = malloc(sizeof(windowHandle)); //<- create new instance of windowHandle for each window
            handle->hWND = wnd;
            handle->title = windowName;
            insert((windowArray*) param, handle); //<- insert each windowHandle in our 'vector'
        }
// but return true here so that we iterate all windows
return TRUE;
}

Call to EnumWindows function:

windowArray* array = array_init(20);
EnumWindows(&delegate, (LPARAM) array); //<- not quite sure what that '&'-sign does?

Structures:

typedef struct windowHandle{
    HWND hWND;
    char* title;
} windowHandle;

typedef struct windowArray{
    int count;
    int capacity;
    int objectSize;
    windowHandle* windows;
} windowArray;

And lastly insert:

int insert(windowArray* array, void* handle){
    int index = (array->count * array->objectSize);
    if(index > 0){
        printf("\n%s %s\n", "first element's title is: ", array->windows->title); //<- prints to see if new handle overwrite the previous ones
    }
    printf("%s %s %s %p %s %d\n", "Inserted element ", ((windowHandle*)handle)->title, " with pointer ", handle, " on index ", index);
    fflush(stdout); //<- prints info about first & current window
    memcpy(array->windows + (index), (windowHandle*)handle, array->objectSize);
    array->count++;
}

Output during insert calls:

Inserted element  joo - Java - nativeWindowCapture/src/NativeWindowHookImp.c - Eclipse SDK  with pointer  0000000000FB1B90  on index  0

first element's title is:  Komentokehote
Inserted element  Komentokehote  with pointer  0000000000FB1BB0  on index  16

first element's title is:  C struct instance overwrites previous instance - Stack Overflow - Mozilla Firefox
Inserted element  C struct instance overwrites previous instance - Stack Overflow - Mozilla Firefox  with pointer  0000000000FB1BD0  on index  32

first element's title is:  JNI compiler kutsu – Muistio
Inserted element  JNI compiler kutsu – Muistio  with pointer  0000000000FB1BF0  on index  48

first element's title is:  Skype™?
Inserted element  Skype™? with pointer  0000000000FB1C10  on index  64

first element's title is:  eclipse
Inserted element  eclipse  with pointer  0000000000FB1C30  on index  80

first element's title is:  src
Inserted element  src  with pointer  0000000000FBCCE0  on index  96
all added

and then if I print the full content of windowArray->windows, I get the following results:

Getting value  src , at index  0  and pointer  0000000000FBBB80
Getting value  src , at index  16  and pointer  0000000000FBBC80
Getting value  src , at index  32  and pointer  0000000000FBBD80
Getting value  src , at index  48  and pointer  0000000000FBBE80
Getting value  src , at index  64  and pointer  0000000000FBBF80
Getting value  src , at index  80  and pointer  0000000000FBC080
Getting value  src , at index  96  and pointer  0000000000FBC180

P.S. I would also like to know why windowArray's windows-attribute's pointers are different from those of *handle-objects created in delegate? That doesn't seem to be very efficient memorywise?

user3738243
  • 159
  • 2
  • 13

1 Answers1

4

You set handle->title to point to windowName. But as soon as you exit this scope, windowName will cease to exist. So your structure contains a pointer to an array that no longer exists.

        char windowName[256] = {};
        GetWindowText(wnd, windowName, sizeof(windowName));
        windowHandle *handle = malloc(sizeof(windowHandle)); //<- create new instance of windowHandle for each window
        handle->hWND = wnd;
        handle->title = windowName;
    }
    // when we get here, windowName ceases to exist
    // so why did we store a pointer to it?

After you exit the scope, it is an error to follow the title pointer, since it no longer points to any object that is still alive. Perhaps change title from char * to char[256].

David Schwartz
  • 179,497
  • 17
  • 214
  • 278