我一直在浏览网站,但尚未找到答案。 用一个例子来解释这个问题是最容易的(至少对我来说)。 我不明白为什么这是有效的: #include int main(int argc, char* argv[]) { char *mystr = “hello”; } 但是这会产生一个编译器警告(“初始化使整数从没有强制转换的整数中生成”): #include int main(int argc, char* argv[]) { int *myint = 5; } 我对第一个程序的理解是创建一个名为mystr的变量,类型为pointer-to-char,其值是字符串文字“hello”的第一个字符(’h’)的地址。 换句话说,使用此初始化,您不仅可以获取指针,还可以定义指针指向的对象(在本例中为“hello”)。 那么,为什么int *myint = 5; 看似没有实现与此类似的东西,即创建一个名为myint的变量类型指针指向int,其值是值’5’的地址? 为什么这个初始化既不给我指针也定义指针所指向的对象?
我有一个函数采用静态二维数组并将数组元素的元素视为常量: void test_function(const char arr[3][3]); 我试着调用如下函数: char my_var[3][3] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; test_function(my_var); 使用gcc编译(没有任何标志)时,我收到以下警告: test.c:9:8: warning: passing argument 1 of ‘test_function’ from incompatible pointer type test_function(my_var); ^ test.c:4:6: note: expected ‘const char (*)[3]’ but argument is of type ‘char (*)[3]’ void test_function(const char arr[3][3]); 如果我从test_function的原型中删除const ,警告就会消失。 但它并不是我想要的。 […]
将类型T的2D数组转换为T*并取消引用元素是否安全? 由于2D数组的存储器布局是线性的,因此基指针应该等于指向第一个元素的指针。 由于它们指向的最终类型也是相同的,因此不应存在任何对齐差异问题。 或者有一些方面会导致未定义的行为? 要明确我的意思是这样的 – int arr[10][10]; int p = *((int*) arr); 另外,同样的问题,如果我访问超出第一个数组的元素,即(int *)arr + 13.它是否属于超出界限的条款? 因为我访问第一个数组的边界之外。
因此,标准(参考N1570 )说明了以下关于比较指针的内容: C99 6.5.8 / 5关系运算符 比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。 … [在聚合中剪切明显的比较定义] … 在所有其他情况下,行为是未定义的。 这个UB实例的基本原理是什么,而不是指定(例如)转换为intptr_t并进行比较? 是否存在一些机器架构,其中指针的合理总排序难以构建? 是否存在一些优化或分析,不受限制的指针比较会阻碍? 这个问题的删除答案提到这块UB允许跳过段寄存器的比较并且仅比较偏移。 保存特别有价值吗? (同样删除的答案,以及此处的答案,请注意,在C ++中, std::less等是实现指针总顺序所必需的,无论普通比较运算符是否执行。)
我有一个文件,我想读取每一行,通过制表符标记它并存储到一个数组中。 但事实certificate,token [0] .. token [4]指向由strtok()产生的每个char的地址。 所以当我在文件的下一行调用strtok时,token [0] … token [4]会改变。 我该如何纠正? 如果我尝试使用char tokens[MAX_SIZE]而不是char* tokens[MAX_SIZE] ,则会发生转换错误,因为strtok返回char *。 该文件是 20 34 90 10 77 80 12 37 29 63 45 21 55 18 46 我的代码是: FILE *f; if ((f = fopen(“myinput.txt”,”r”)) == NULL) { perror(“Failed to open file:”); return -1; } char * line; size_t len […]
使用此代码: #include void printSize(char *messages[]) { printf(“%d”, sizeof(messages) / sizeof(char *)); } int main(void) { printf(“Size when through passing direct to function: “); printSize((char *[]){“Zero”, “One”, “Two”, “Three”}); printf(“\n”); printf(“Size when calculating in main: %d\n”, sizeof((char *[]){“Zero”, “One”, “Two”, “Three”}) / sizeof(char *)); return 1; } 我得到输出: Size when through passing direct to function: 1 […]
假设我有一个用这样的东西创建的二维数组, char **foo = (char **) malloc(height * sizeof(char *)); for(i = 0; i <= height; i++) foo[i] = (char *) malloc (width * sizeof(char *)); 首先,这甚至是创建像这样的数组的正确方法吗? 这里的问题是,’height’和’width’是在运行时设置的东西。 这似乎有效,但这是释放这个2Darrays的最佳策略。 免费(funge)听起来不对。 通过这里的其他post,我想我会逐一释放每一行? 我确实试过这样的事, for (height = 0; height funge_height; height++) { free(funge[height]); } free(funge) 然而,这给了我一个双重自由指针exception。 这是不是意味着,我不需要管理这段记忆? 我的印象是,对于每个malloc的内存,我们应该调用free()。
这个网站上有很多关于在使用后释放指针的问题,并且进一步将它们设置为NULL。 争论很激烈,主题看似平分。 例如: 这个问题 。 一般来说,我对释放指针很困惑。 想象一下,你有一个指向一些内存空间的指针。 使用空格后,释放指针但不将其设置为NULL。 稍后,你有另一个指针调用malloc()或一些模拟,它被分配内存,包括先前释放的内存(原始指针仍指向)。 如果这个新指针写入此内存块,会发生什么? 直觉上什么都不会发生,但早先提供的链接中的OP写道它会使程序崩溃。 所以我的问题是: 给定一个释放指针,是什么阻止您将指针重新分配给新的内存位置? 为什么重用已释放的指针是“坏”的做法? 如果调用free(ptr)只将此内存返回给操作系统,为什么不能重新分配指针以便其他内存位置并重用它? char *ptr = malloc(sizeof(*ptr)); //first allocation free(ptr); //release memory ptr = NULL; ptr = malloc(sizeof(*ptr)); //reallocate 为什么写入以前释放的内存块,仍然有原始指针,导致程序崩溃? – 请参阅上面链接的问题的第一篇文章的第一段(如果我误解了本段的意图,请解释,因为不明确是否再次使用该指针来写入内存或创建新指针。)
我知道这不起作用,因为变量x在函数返回时被销毁: int* myFunction() { int x = 4; return &x; } 那么如何正确地返回指向我在函数中创建的东西的指针,以及我需要注意什么? 如何避免内存泄漏? 我也用过malloc: int* myFunction2() { int* x = (int*)malloc(sizeof int); *x = 4; return x; } 你是如何正确地做到这一点的 – 在C和C ++中?
我有一个函数,它接受一个字符串,一个字符串数组和一个指针数组,并在字符串数组中查找字符串,并从指针数组返回相应的指针。 因为我将它用于几个不同的东西,指针数组被声明为(void *)的数组,并且调用者应该知道实际存在哪种指针(因此它返回的返回值是什么类型的指针) )。 但是当我传入一个函数指针数组时,我在使用-Wpedantic编译时会收到警告: 铛: test.c:40:8: warning: assigning to ‘voidfunc’ (aka ‘void (*)(void)’) from ‘void *’ converts between void pointer and function pointer [-Wpedantic] GCC: test.c:40:8: warning: ISO C forbids assignment between function pointer and ‘void *’ [-Wpedantic] fptr = find_ptr(“quux”, name_list, (void **)ptr_list, 这是一个测试文件,尽管警告确实正确打印“quux”: #include #include void foo(void) { puts(“foo”); } void bar(void) […]