【问题标题】:C struct instance overwrites previous instanceC 结构实例覆盖前一个实例
【发布时间】:2017-11-14 09:19:44
【问题描述】:

我是 C 新手,所以答案可能很明显,但我无法理解它。

我正在尝试创建C++ vector kind of structure in C。我使用 Windows EnumWindows 函数循环遍历所有窗口。在回调函数中,我为每个窗口创建了 windowHandle 结构的新实例。但是由于某种原因,它似乎并没有创建新实例,而是覆盖了旧实例。或者它可能会创建新实例,但是当我为属性 windowHandle->title 赋值时,它会将更改应用于 windowHandle 的每个实例?

回调函数:

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;
}

调用 EnumWindows 函数:

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

结构:

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

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

最后插入:

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++;
}

插入调用期间的输出:

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

然后如果我打印windowArray->windows的全部内容,我会得到以下结果:

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

附:我也想知道为什么windowArray的windows-attribute的指针与在delegate中创建的*handle-objects的指针不同?这在记忆方面似乎不是很有效?

【问题讨论】:

    标签: c pointers struct malloc memcpy


    【解决方案1】:

    您将handle-&gt;title 设置为指向windowName。但是,一旦您退出此范围,windowName 将不复存在。所以你的结构包含一个指向不再存在的数组的指针。

            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?
    

    退出作用域后,跟随title 指针是错误的,因为它不再指向任何仍然存在的对象。也许将titlechar * 更改为char[256]

    【讨论】:

    • 哦,有道理。谢谢!拯救了这一天。
    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2012-07-19
    • 1970-01-01
    • 2012-04-24
    • 2020-05-11
    • 1970-01-01
    相关资源
    最近更新 更多