- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用与其 typedef 相同的名称命名对象时,会看到一些不寻常的行为。
当我定义 _same_names_ 时,clist_create 中的声明将扩展为
clist *clist;
/*
* naming-test.c
* Strange behaviour when using the same name for an object as its typedef eg.
* clist *clist; //where clist is a typedef
*/
#include <stdio.h>
#include <stdlib.h>
typedef void *(*allocator_t)(size_t size);
typedef void (*deallocator_t)(void *obj);
typedef struct clist
{
void *data;
struct clist *next;
struct clist *prev;
allocator_t allocate;
deallocator_t deallocate;
}clist;
/* simple wrapper so we can log the allocd memory */
void *log_alloc(size_t size)
{
void *ptr = malloc(size);
fprintf(stdout, "+%p\n", ptr);
return ptr;
}
/* logs the freed memory */
void log_free(void *ptr)
{
fprintf(stdout, "-%p\n", ptr);
free(ptr);
}
#ifdef _same_name_
#define my_clist_object_name clist
#else /* different names */
#define my_clist_object_name clist_base
#endif
clist *clist_create(int objsize, int units_in_block, allocator_t allocator, deallocator_t deallocator)
{
allocator_t default_allocator = malloc;
deallocator_t default_deallocator = free;
clist *my_clist_object_name;
if(!allocator || !deallocator)
{
allocator = default_allocator;
deallocator = default_deallocator;
}
my_clist_object_name = allocator( /* line 53 */
sizeof(clist));
if(!my_clist_object_name)
{
goto err0;
}
my_clist_object_name->data = 0;
my_clist_object_name->next = 0; /* line 60 */
my_clist_object_name->prev = 0;
my_clist_object_name->allocate = allocator; /* line 62 */
my_clist_object_name->deallocate = deallocator;
return my_clist_object_name;
err0:
return 0;
}
void clist_delete(clist *clist_head)
{
clist *cursor, *next;
cursor = clist_head;
while(cursor)
{
next = cursor->next;
cursor->deallocate(cursor); /* line 77 */
cursor = next;
}
}
void test_clist_create()
{
clist *clist_renamed = clist_create(sizeof(int), 2, &log_alloc, &log_free);
if(!clist_renamed)return ;
clist_delete(clist_renamed);
}
int main()
{
test_clist_create();
fprintf(stdout, "not crashing anymore!!\n");
return 0;
}
#Makefile for naming-test.c
CFLAGS=-g -Wall -std=c89
same_names:
gcc ${CFLAGS} -D_same_name_ naming-test.c -o same_names
different_names:
gcc ${CFLAGS} naming-test.c -o different_names
clean:
rm -f same_names different_names
(gdb) bt
#0 0x00007ffff7a85475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff7a886f0 in *__GI_abort () at abort.c:92
#2 0x00007ffff7ac052b in __libc_message (do_abort=<optimized out>, fmt=<optimized out>) at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3 0x00007ffff7ac9d76 in malloc_printerr (action=3, str=0x7ffff7ba2190 "free(): invalid next size (fast)", ptr=<optimized out>)
at malloc.c:6283
#4 0x00007ffff7aceaac in *__GI___libc_free (mem=<optimized out>) at malloc.c:3738
#5 0x00000000004006b0 in log_free (ptr=0x601010) at naming-test.c:34
#6 0x0000000000400788 in clist_delete (clist_head=0x601010) at naming-test.c:77
#7 0x00000000004007d1 in test_clist_create () at naming-test.c:85
#8 0x00000000004007e4 in main () at naming-test.c:90
$ ./different_names
+0xb88010
-0xb88010
not crashing anymore!!
$ valgrind ./same_names
==8707== Memcheck, a memory error detector
==8707== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8707== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8707== Command: ./same_names
==8707==
+0x51b9040
==8707== Invalid write of size 8
==8707== at 0x40071B: clist_create (naming-test.c:60)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9048 is 0 bytes after a block of size 8 alloc'd
==8707== at 0x4C28BED: malloc (vg_replace_malloc.c:263)
==8707== by 0x400653: log_alloc (naming-test.c:25)
==8707== by 0x400700: clist_create (naming-test.c:53)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707==
==8707== Invalid write of size 8
==8707== at 0x400727: clist_create (naming-test.c:61)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9050 is 8 bytes after a block of size 8 alloc'd
==8707== at 0x4C28BED: malloc (vg_replace_malloc.c:263)
==8707== by 0x400653: log_alloc (naming-test.c:25)
==8707== by 0x400700: clist_create (naming-test.c:53)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707==
==8707== Invalid write of size 8
==8707== at 0x400737: clist_create (naming-test.c:62)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9058 is not stack'd, malloc'd or (recently) free'd
==8707==
==8707== Invalid write of size 8
==8707== at 0x400743: clist_create (naming-test.c:63)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9060 is not stack'd, malloc'd or (recently) free'd
==8707==
==8707== Invalid read of size 8
==8707== at 0x40076F: clist_delete (naming-test.c:76)
==8707== by 0x4007D0: test_clist_create (naming-test.c:85)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9048 is 0 bytes after a block of size 8 alloc'd
==8707== at 0x4C28BED: malloc (vg_replace_malloc.c:263)
==8707== by 0x400653: log_alloc (naming-test.c:25)
==8707== by 0x400700: clist_create (naming-test.c:53)
==8707== by 0x4007B9: test_clist_create (naming-test.c:83)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707==
==8707== Invalid read of size 8
==8707== at 0x40077B: clist_delete (naming-test.c:77)
==8707== by 0x4007D0: test_clist_create (naming-test.c:85)
==8707== by 0x4007E3: main (naming-test.c:90)
==8707== Address 0x51b9060 is not stack'd, malloc'd or (recently) free'd
==8707==
-0x51b9040
not crashing anymore!!
==8707==
==8707== HEAP SUMMARY:
==8707== in use at exit: 0 bytes in 0 blocks
==8707== total heap usage: 1 allocs, 1 frees, 8 bytes allocated
==8707==
==8707== All heap blocks were freed -- no leaks are possible
==8707==
==8707== For counts of detected and suppressed errors, rerun with: -v
==8707== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 4 from 4)
$ valgrind ./different_names
==11207== Memcheck, a memory error detector
==11207== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==11207== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==11207== Command: ./different_names
==11207==
+0x51b9040
-0x51b9040
not crashing anymore!!
==11207==
==11207== HEAP SUMMARY:
==11207== in use at exit: 0 bytes in 0 blocks
==11207== total heap usage: 1 allocs, 1 frees, 40 bytes allocated
==11207==
==11207== All heap blocks were freed -- no leaks are possible
==11207==
==11207== For counts of detected and suppressed errors, rerun with: -v
==11207== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
最佳答案
尽管对类型和变量使用相同的标识符是合法的,但这不是一个好主意。任何阅读代码的人都会感到困惑,也可能会让您感到困惑,因为它会造成一些歧义。
其中之一是:
sizeof(clist) // line 54
clist
既是类型又是变量名,其中一个用于
sizeof
? [1] 这很重要,因为变量
clist
类型为
clist*
因此变量的大小比变量指向的结构的大小要小得多;您需要为包含三个指针和两个函数指针的结构分配足够的空间,而您只为单个指针分配了足够的空间。对结构成员的后续写入将覆盖随机内存。
sizeof
通过显式返回结构的大小:
sizeof(struct clist)
CList
.
关于c - 异常行为 : typedef and object of same name,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20157781/
我遵循了一本名为“Sitepoint Full Stack Javascript with MEAN”的书中的教程,我刚刚完成了第 6 章,应该已经创建了一个带有“数据库”的“服务器”。数据库只不过是
在 Jquery 中,我创建两个数组,一个嵌入另一个数组,就像这样...... arrayOne = [{name:'a',value:1}, {name:'b',value:2}] var arra
这个问题在这里已经有了答案: What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wa
我被放在别人的代码上,有一个类用作其他组件的基础。当我尝试 ng serve --aot(或 build --prod)时,我得到以下信息。 @Component({ ...,
我正在测试一些代码,并使用数据创建了一个 json 文件。 问题是我在警报中收到“[object Object],[object Object]”。没有数据。 我做错了什么? 这是代码:
我想打印 [object Object],[object Object] 以明智地 "[[{ 'x': '1', 'y': '0' }, { 'x': '2', 'y': '1' }]]"; 在 ja
我有一个功能 View ,我正在尝试以特殊格式的方式输出。但我无法让列表功能正常工作。 我得到的唯一返回是[object Object][object Object] [object Object]
在使用优秀的 Sim.js 和 Three.js 库处理 WebGL 项目时,我偶然发现了下一个问题: 一路走来,它使用了 THREE.Ray 的下一个构造函数: var ray = new THRE
我正在使用 Material UI 进行多重选择。这是我的代码。 {listStates.map(col => (
我的代码使用ajax: $("#keyword").keyup(function() { var keyword = $("#keyword").val(); if (keyword.
我遇到了下一个错误,无法理解如何解决它。 Can't resolve all parameters for AuthenticationService: ([object Object], ?, [o
我正在尝试创建一个显示动态复选框的表单,至少应选中其中一个才能继续。我还需要获取一组选中的复选框。 这是组件的代码: import { Component, OnInit } from '@angul
我正在开发 NodeJs 应用程序,它是博客应用程序。我使用了快速验证器,我尝试在 UI 端使用快速闪存消息将帖子保存在数据库中之前使用闪存消息验证数据,我成功地将数据保存在数据库中,但在提交表单后消
我知道有些人问了同样的问题并得到了解答。我已经查看了所有这些,但仍然无法解决我的问题。我有一个 jquery snipet,它将值发送到处理程序,处理程序处理来自 JS 的值并将数据作为 JSON 数
我继承了一个非常草率的项目,我的任务是解释为什么它不好。我注意到他们在整个代码中都进行了这样的比较 (IQueryable).FirstOrDefault(x => x.Facility == fac
我只是在删除数组中的对象时偶然发现了这一点。 代码如下: friends = []; friends.push( { a: 'Nexus', b: 'Muffi
这两个代码片段有什么区别: object = nil; [object release] 对比 [object release]; object = nil; 哪个是最佳实践? 最佳答案 object
我应该为其他人将从中继承的第一个父对象传递哪个参数,哪个参数更有效 Object.create(Object.prototype) Object.create(Object) Object.creat
我在不同的对象上安排不同的选择器 [self performSelector:@selector(doSmth) withObject:objectA afterDelay:1]; [self per
NSLog(@"%p", &object); 和 NSLog(@"%p", object); 有什么区别? 两者似乎都打印出一个内存地址,但我不确定哪个是对象的实际内存地址。 最佳答案 这就是我喜欢的
我是一名优秀的程序员,十分优秀!