我遇到了这样一种情况:对不必要的调用realloc进行优化会很有用.然而,似乎既没有铿锵也没有gcc做这样的事情(Godbolt).- 虽然我看到通过多次调用进行优化malloc.
这个例子:
void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}
Run Code Online (Sandbox Code Playgroud)
我希望它能够优化到以下内容:
void *myfunc() {
return malloc(200);
}
Run Code Online (Sandbox Code Playgroud)
为什么clang和gcc都没有优化它? - 他们不允许这样做吗?
我有一个简单的函数,它计算字符串中的字母t:
#include <stdio.h>
#include <string.h>
static int count_t_letters(const char *t) {
int r;
r = 0;
while(*t) {
if(*t == 't') {
++r;
}
++t;
}
return r;
}
int main() {
printf("%i", count_t_letters("test"));
}
Run Code Online (Sandbox Code Playgroud)
这是我期待的优化:
int main() {
printf("%i", 2);
}
Run Code Online (Sandbox Code Playgroud)
为什么这个简单的功能没有像我在gcc和clang中预期的那样优化?(godbolt)
到目前为止我想到了什么:
我在看std :: string :: max_size并注意到了这个例子:
#include <iostream>
#include <string>
int main ()
{
std::string str ("Test string");
std::cout << "max_size: " << str.max_size() << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
与输出:
max_size: 4294967291
Run Code Online (Sandbox Code Playgroud)
但是,我一直认为这个限制是由无符号整数/ size_t的最大值引起的 - 所以我有点期待它2^32 - 1会是什么4294967295.为什么此示例中的最大大小不使用这4个字节?
我也尝试运行示例代码,并在那台机器上2^62- 这再次让我感到困惑,为什么不2^64 - 1相反呢?
总的来说,我想知道,由于什么原因,实现不会使用所有空间?
我目前正在寻找一种“单数化”英语单词的方法。我找到了相反的方法。这是我到目前为止所想出的:
\n\nfunction singularize(word) {\n const endings = {\n ves: \'fe\',\n ies: \'y\',\n i: \'us\',\n zes: \'\',\n ses: \'\',\n es: \'\',\n s: \'\'\n };\n return word.replace(\n new RegExp(`(${Object.keys(endings).join(\'|\')})$`), \n r => endings[r]\n );\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然而,这在很多情况下不起作用(例如分析\xe2\x80\x93分析、现象\xe2\x80\x93现象、系列\xe2\x80\x93系列)。有没有更准确的方法来做到这一点而不嵌入整个字典?有没有办法访问浏览器的字典?
\n\n如果没有字典就没有办法,那么至少稍微准确一点的解决方案是什么?
\n我正在阅读 C 标准中的以下内容:
(6.5.6 加法运算符)
9 当两个指针相减时,两个指针都指向同一个数组对象的元素,或者指向数组对象最后一个元素之后的一个;结果是两个数组元素的下标之差。
现在我想知道什么被认为是“数组对象”。更具体地说,我想知道下面这个愚蠢的例子是否合法?该分配的内存块是否被视为一个“数组对象”?
uint8_t *data = malloc(255);
uint8_t *end = data + 255;
ptrdiff_t size = end - data;
Run Code Online (Sandbox Code Playgroud) 我目前想知道严格别名规则背后的基本原理.我知道C中不允许使用某些别名,并且目的是允许优化,但我很惊讶这是在定义标准时跟踪类型转换的首选解决方案.
所以,显然下面的例子违反了严格的别名规则:
uint64_t swap(uint64_t val)
{
uint64_t copy = val;
uint32_t *ptr = (uint32_t*)© // strict aliasing violation
uint32_t tmp = ptr[0];
ptr[0] = ptr[1];
ptr[1] = tmp;
return copy;
}
Run Code Online (Sandbox Code Playgroud)
我可能是错的,但据我所知,编译器应该完全和平凡地能够跟踪类型转换并避免对任何事物上显式转换的类型进行优化(就像它避免对同类型指针进行优化)用受影响的值调用.
那么,严格的别名规则存在哪些问题我错过了编译器无法轻易解决自动检测可能的优化问题)?
读完这篇文章后,我有一个类似的问题,想知道内存分配器如何在不违反严格别名规则的情况下工作。但我并不想知道重新使用释放的内存,我想知道如何在不违反严格别名的情况下将分配的对象定位在线性内存中。
到目前为止,我见过的所有堆内存分配器都将内存划分为某种块,并在前面有一个标头。然而,malloc 返回 avoid *并且通常指向标头后面的内存。这是一个非常缩小的例子来说明这一点。
#include <stddef.h>
struct block_header {
size_t size;
};
struct block_header *request_space(size_t size);
void *malloc(size_t size) {
struct block_header *block = request_space(size);
// I guess this violates strict aliasing, because the caller will
// convert the pointer to something other than struct block_header?
// Or why wouldn't it?
return block + 1;
}
Run Code Online (Sandbox Code Playgroud)
我已经研究这个问题有一段时间了,但我看不出分配器如何在不违反严格别名的情况下将其指针定位在内存区域中。我缺少什么?
我目前正在尝试找出哪个函数使用MutationObserver. 不幸的是,以下代码段不起作用(堆栈跟踪似乎是空的)。
var targetNode = document.body;
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(var mutation of mutationsList) {
// The trace unfortunatelly doesn't contain the function
// "addSomeElement", which I am trying to receive at this point.
console.trace();
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
Run Code Online (Sandbox Code Playgroud)
接下来是一些 DOM 突变:
function addSomeElement() {
targetNode.appendChild(document.createElement('span'));
}
addSomeElement();
Run Code Online (Sandbox Code Playgroud)
有什么办法可以输出执行实际突变调用的函数(在这种情况下是appendChild)?
我一直在阅读“如何重新分配使用 calloc 分配的一些内存? ”。现在我想知道如果块更大,arealloc后跟 a是否calloc会将新字节归零。
愚蠢的例子:
#include <stdlib.h>
#include <string.h>
int test() {
char *mem;
mem = calloc(100, 1);
mem = realloc(mem, 120);
memset(mem + 100, 0, 20); // is this even necessary?
}
Run Code Online (Sandbox Code Playgroud)
我已经对其进行了测试,似乎已将其归零 - 但我不确定是否总是如此?