小编gaa*_*kam的帖子

我可以通过为封闭结构分配更多空间来"过度扩展"数组吗?

坦率地说,这样的代码是有效还是产生UB?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct __attribute__((__packed__)) weird_struct
{
    int some;
    unsigned char value[1];
};

int main(void)
{
    unsigned char text[] = "Allie has a cat";
    struct weird_struct *ws =
        malloc(sizeof(struct weird_struct) + sizeof(text) - 1);
    ws->some = 5;
    strcpy(ws->value, text);
    printf("some = %d, value = %s\n", ws->some, ws->value);
    free(ws);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/lpByQD

我永远不会认为它对这样的事情是有效的,但似乎SystemV消息队列就是这样做的:参见手册页.

所以,如果SysV msg队列可以做到这一点,也许我也可以这样做?我想我发现通过网络发送数据很有用(因此__attribute__((__packed__))).

或者,这可能是SysV msg队列的特定保证,我不应该在其他地方做类似的事情吗?或者,也许这种技术可以使用,只有我做错了?我想出来我最好问一下.

- 1malloc(sizeof(struct weird_struct) + sizeof(text) - 1)是因为我考虑到一个字节分配反正感谢unsigned char value[1],所以我可以从减去它 …

c arrays undefined-behavior language-lawyer flexible-array-member

24
推荐指数
1
解决办法
793
查看次数

如何将N个整数读入向量?

如果我想从标准输入到向量读取所有整数,我可以使用方便:

vector<int> v{istream_iterator<int>(cin), istream_iterator()};
Run Code Online (Sandbox Code Playgroud)

但我们假设我只想读取n整数.手动打字循环是我得到的一切吗?

vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
    cin >> v[i];
Run Code Online (Sandbox Code Playgroud)

还是有更多的右手方式来做到这一点?

c++ input vector

18
推荐指数
2
解决办法
979
查看次数

为什么线程同步不需要volatile关键字?

我正在读这个volatile关键字不适合线程同步,事实上根本不需要这些关键字.

虽然我知道使用这个关键字是不够的,但我不明白为什么它完全没必要.

例如,假设我们有两个线程,线程A仅从共享变量读取,线程B仅写入共享变量.通过例如pthreads互斥锁实现适当的同步.

IIUC,没有volatile关键字,编译器可能会查看线程A的代码并说:"这里的变量似乎没有被修改,但是我们有很多读取; 让我们只读一次,缓存值并优化所有后续读取."它也可以查看线程B的代码并说:"我们在这里有很多写这个变量但没有读取; 因此,不需要写入值,因此我们可以优化所有写入."

两种优化都是不正确的.和 挥发性会阻止一个人.所以,我可能会得出这样的结论:虽然volatile不足以同步线程,但仍然需要在线程之间共享任何变量.(注意:我现在读到,实际上并不需要volatile防止写入成功;所以我没有想法如何防止这种不正确的优化)

我明白我错在这里.但为什么?

c c++ multithreading volatile

14
推荐指数
1
解决办法
747
查看次数

Linux是否保证在程序退出时释放malloc'd不同的内存?

我曾经相信它确实存在但是...我无法明确说明它.

man 3 exitman 2 _exit详细说明了进程终止的影响,但没有提到内存泄漏.

Posix走近了:它提到了这个:

  • 在进程被销毁之前,应该在进程中创建的内存映射取消映射.

  • [TYM] [Option Start]在调用进程中映射的任何类型内存块都应取消映射,就像munmap()隐式调用它们取消映射它们一样.[选项结束]

混合这个man 3 malloc:

通常,malloc()从堆中分配内存,并根据需要使用调整堆的大小sbrk(2).当分配大于MMAP_THRESHOLD字节的内存块时,glibc malloc()实现将内存分配为私有匿名映射使用mmap(2).

因此,我们可以得出结论,如果malloc调用,mmap则进程终止可能会进行相应的调用munmap,但是......(a)此POSIX规范中的这个"可选功能"标记令人担忧,(b)这是mmap怎么回事sbrk?(c)Linux不是100%符合POSIX,所以我不确定是否强制将Linux文档与Posix规范混合使用

我问的原因是这个......当图书馆通话失败时,我是否可以退出?

if(somecall() == -1) {
    error(EXIT_FAILURE, errno, "Big fat nasty error.\n");
}
Run Code Online (Sandbox Code Playgroud)

还是我上去栈确保一切都一路攀升到main()free()"d和来电exiterrormain()

前者简单得多.但是为了让前者感到轻松,我想在明确提到的文档中找到它,这不是一个错误,这样做是安全的.正如我所说的那样,事实上,文档明确提到了一些肯定会被清理的保证,但没有提到这个特定的保证让我感到不安.(这不是最常见和最明显的案例吗?首先不会提到这个吗?)

malloc posix memory-leaks terminate language-lawyer

13
推荐指数
2
解决办法
412
查看次数

如何有效地计算小于或等于给定数字的2的最高功率?

到目前为止我想出了三个解决方案:

极低效的标准库powlog2功能:

int_fast16_t powlog(uint_fast16_t n)
{
  return static_cast<uint_fast16_t>(pow(2, floor(log2(n))));
}
Run Code Online (Sandbox Code Playgroud)

计算后续2次幂的效率要高得多,直到我达到的数量超过我必须达到的数量:

uint_fast16_t multiply(uint_fast16_t n)
{
  uint_fast16_t maxpow = 1;
  while(2*maxpow <= n)
    maxpow *= 2;
  return maxpow;
}
Run Code Online (Sandbox Code Playgroud)

到目前为止最有效的binsearching预先计算的2的权力表:

uint_fast16_t binsearch(uint_fast16_t n)
{
  static array<uint_fast16_t, 20> pows {1,2,4,8,16,32,64,128,256,512,
    1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};

  return *(upper_bound(pows.begin(), pows.end(), n)-1);
}
Run Code Online (Sandbox Code Playgroud)

这可以进一步优化吗?可以在这里使用的任何技巧?

我使用的完整基准:

#include <iostream>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <array>
#include <algorithm>
using namespace std;
using namespace chrono;

uint_fast16_t powlog(uint_fast16_t n)
{
  return static_cast<uint_fast16_t>(pow(2, floor(log2(n))));
}

uint_fast16_t multiply(uint_fast16_t n)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ optimization

12
推荐指数
1
解决办法
1417
查看次数

为什么第二次处理数组的速度较慢?

这个简单的C代码首先创建一个0xFFFFFF元素的数组,然后传递两次,测量每次传递所花费的时间:

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TESTSIZ 0xffffff

char testcases[TESTSIZ];

void gentestcases(void)
{
        size_t i = 0;
        while(i < TESTSIZ)
                testcases[i++] = rand()%128;

        return;
}

long long time_elapsed(struct timespec beg, struct timespec end)
{
        if(end.tv_nsec < beg.tv_nsec) {
                end.tv_nsec += 1000000000;
                end.tv_sec--;
        }

        return 1000000000ll*(end.tv_sec-beg.tv_sec) + end.tv_nsec-beg.tv_nsec;
}

long long test( int(*func)(int) )
{
        struct timespec beg, end;

        clock_gettime(CLOCK_MONOTONIC, &beg);

        int volatile sink;
        size_t i = 0;
        while(i < TESTSIZ)
                sink = islower(testcases[i++]);

        clock_gettime(CLOCK_MONOTONIC, &end);

        return …
Run Code Online (Sandbox Code Playgroud)

c arrays performance

12
推荐指数
1
解决办法
171
查看次数

为什么在似乎是数据副本的操作上修改原始数据?

让我们引用numpy手册:https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing

当选择对象obj是非元组序列对象,ndarray(数据类型为integer或bool)或具有至少一个序列对象或ndarray(数据类型为integer或bool)的元组时,将触发高级索引.高级索引有两种类型:整数和布尔值.

高级索引始终返回数据的副本(与返回视图的基本切片形成对比).

然后对高级索引返回的内容进行操作永远不应该修改原始数组.事实上:

import numpy as np

arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])

slicedArr = arr[indexes]
slicedArr *= 5
arr
Run Code Online (Sandbox Code Playgroud)

这打印:

array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
Run Code Online (Sandbox Code Playgroud)

但是,情况似乎并非总是如此.奇怪的是,如果我不保存[]操作符返回的任何中间变量,我会以某种方式在原始数组上操作.请考虑这个例子:

import numpy as np

arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])

arr[indexes] *= 5
arr
Run Code Online (Sandbox Code Playgroud)

这打印:

array([  0,  10,  20, …
Run Code Online (Sandbox Code Playgroud)

python arrays numpy copy

9
推荐指数
1
解决办法
230
查看次数

为什么序列[getLine,getLine,getLine]的计算没有被延迟?

main = do
  input <- sequence [getLine, getLine, getLine]
  mapM_ print input
Run Code Online (Sandbox Code Playgroud)

让我们看看这个程序的实际效果:

m@m-X555LJ:~$ runhaskell wtf.hs
asdf
jkl
powe
"asdf"
"jkl"
"powe"
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,这里似乎没有懒惰。取而代之getLine的是,急切地评估所有3个值,将读取的值存储在内存中,然后而不是在此之前将所有值打印出来。

比较一下:

main = do
  input <- fmap lines getContents
  mapM_ print input
Run Code Online (Sandbox Code Playgroud)

让我们看一下实际情况:

m@m-X555LJ:~$ runhaskell wtf.hs
asdf
"asdf"
lkj
"lkj"
power
"power"
Run Code Online (Sandbox Code Playgroud)

完全不同的东西。行被一一读取并一一打印。这对我来说很奇怪,因为我看不到这两个程序之间有什么区别。

从LearnYouAHaskell:

当I / O操作所使用,sequenceA是同样的事情sequence!它获取I / O操作的列表,并返回将执行这些操作中的每个操作的I / O操作,并以结果的形式列出这些I / O操作的结果。这是因为要将一个[IO a]值转换为一个IO [a]值,以使一个I / O操作在执行时产生结果列表,所以所有这些I / O操作都必须先进行排序,以便在评估时依次执行。被迫。如果不执行I / O操作,则无法获得结果。

我糊涂了。我不需要执行所有IO操作就可以得到一个结果。

该书前面几段显示了以下内容的定义sequence

sequenceA :: …
Run Code Online (Sandbox Code Playgroud)

recursion haskell sequence lazy-evaluation

8
推荐指数
1
解决办法
79
查看次数

可以通过fseek()读取整个文件到SEEK_END并通过ftell()获取文件大小吗?

我是对的,这段代码引入了未定义的行为?

#include <stdio.h>
#include <stdlib.h>

FILE *f = fopen("textfile.txt", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);  //same as rewind(f);

char *string = malloc(fsize + 1);
fread(string, fsize, 1, f);
fclose(f);

string[fsize] = 0;
Run Code Online (Sandbox Code Playgroud)

我之所以要问的是,这段代码是作为以下问题的一个被接受且高度评价的答案发布的:C编程:如何将整个文件内容读入缓冲区

但是,根据以下文章:如何在C++中读取整个文件到内存中(尽管它的标题,它也处理C,所以坚持我):

假设您正在编写C,并且您有FILE*(您知道指向文件流,或者至少是可搜索流),并且您想要确定在缓冲区中分配多少个字符来存储流的全部内容.你的第一直觉可能是编写这样的代码:

// Bad code; undefined behaviour
fseek(p_file, 0, SEEK_END);
long file_size = ftell(p_file);
Run Code Online (Sandbox Code Playgroud)

似乎是合法的.但后来你开始变得怪异了.有时报告的大小大于磁盘上的实际文件大小.有时它与实际文件大小相同,但您读入的字符数不同.这到底是怎么回事?

有两个答案,因为它取决于文件是以文本模式还是以二进制模式打开.

万一你不知道区别:在默认模式 - 文本模式 - 在某些平台上,某些字符在阅读过程中会以各种方式被翻译.最着名的是,在Windows上,新行在\r\n写入文件时会被翻译,并在读取时以其他方式翻译.换句话说,如果文件包含Hello\r\nWorld,则将其读作Hello\nWorld; 文件大小为12个字符,字符串大小为11.鲜为人知的是 0x1A(或Ctrl-Z)被解释为文件的结尾,因此如果文件包含Hello\x1AWorld,则将其读作Hello.此外,如果内存中的字符串是,Hello\x1AWorld …

c stream file-read undefined-behavior

7
推荐指数
1
解决办法
964
查看次数

Reader monad可以执行的应用功能不能做什么?

阅读http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors之后,我可以提供一个将函数用作应用函子的示例:

比方说res是4个参数和功能fafbfcfd是采取单一参数的所有功能。然后,如果我没记错的话,此适用表达式:

f <$> fa <*> fb <*> fc <*> fd $ x
Run Code Online (Sandbox Code Playgroud)

与此非特殊表达式的含义相同:

f (fa x) (fb x) (fc x) (fd x)
Run Code Online (Sandbox Code Playgroud)

啊。我花了很多时间来理解为什么会这样,但是-在一张纸上放着我的笔记的帮助下-我应该能够证明这一点。

然后,我阅读了http://learnyouahaskell.com/for-a-few-monads-more#reader。我们再次以monadic语法重新介绍了这些内容:

do
    a <- fa
    b <- fb
    c <- fc
    d <- fd
    return (f a b c d)
Run Code Online (Sandbox Code Playgroud)

尽管我需要另一张A4笔记来证明这一点,但我现在非常有信心,这也意味着相同:

    f (fa x) (fb x) (fc x) (fd x)
Run Code Online (Sandbox Code Playgroud)

我糊涂了。为什么?这有什么用?

或者,更准确地说:在我看来,这只是复制了函数的功能作为应用程序,但语法更为冗长。

因此,您能否举一个例子,说明Reader monad能否像应用程序那样起作用?

其实,我也想问问有什么用任何这些二:应用性功能或阅读器单子-因为同时能够同样的论点适用于四种功能(fafbfcfd …

monads haskell applicative reader-monad

7
推荐指数
2
解决办法
246
查看次数