相关疑难解决方法(0)

(为什么)使用未初始化的变量未定义行为?

如果我有:

unsigned int x;
x -= x;
Run Code Online (Sandbox Code Playgroud)

很明显,x 应该这样表达后是零,但到处看,他们说的行为,这种代码是不确定的,而不是仅仅值x(直到减法之前).

两个问题:

  • 这段代码的行为确实未定义吗?
    (例如,代码在兼容系统上崩溃[或更糟]?)

  • 如果是这样,为什么 C表示行为是未定义的,当非常清楚x这里应该为零时?

    即不在此定义行为给出的优势是什么?

很明显,编译器可以简单地使用它在变量中认为"方便"的任何垃圾值,并且它可以按预期工作......这种方法有什么问题?

c initialization undefined-behavior

77
推荐指数
6
解决办法
1万
查看次数

为什么创建了register关键字?

在阅读Herb Sutter撰写的关键词(或其他名称)时,我遇到了以下几点:

没错,有些关键字在语义上等同于空格,这是一个美化的评论.

我们已经看到为什么C++语言将关键字视为保留字,我们已经看到两个关键字-auto和register--它们对C++程序没有任何语义差异.不要使用它们; 无论如何,它们只是空格,并且有更快的方式来输入空格.

如果关键字auto(可能不是在C++ 11中)并且register没有价值,那么它们为什么被创建和使用?

如果包含register变量之前没有任何区别

#include<stdio.h>
int main(){
    register int a = 15;
    printf("%d\n%d\n",&a,a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么上述程序会出错?

test_register.c:在函数'main'中:

test_register.c:4:2:错误:请求的寄存器变量'a'的地址

的printf( "%d \n%d \n",&A,A);

以下程序适用于C++.

#include<iostream>
int main(){
    register int a = 15;
    std::cout<<&a<<'\n'<<a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c c++ language-lawyer c++11

44
推荐指数
3
解决办法
7265
查看次数

从未初始化的变量memcpy是未定义的行为吗?

是使用未初始化的变量作为srcmemcpy用C未定义行为?

void foo(int *to)
{
  int from;
  memcpy(to, &from, sizeof(from));
}
Run Code Online (Sandbox Code Playgroud)

c memcpy undefined-behavior language-lawyer

21
推荐指数
2
解决办法
1835
查看次数

这种自我指派是否做了明智的事情?

我刚刚在一个函数中找到了这行代码,这让我很困惑.这在任何情况下都有意义,还是未定义的行为?

char * acFilename = acFilename;
Run Code Online (Sandbox Code Playgroud)

编辑:编译器抱怨警告C4700,我正在使用未初始化的变量.

c c++

20
推荐指数
3
解决办法
4070
查看次数

这个❤代码是如何工作的?

我偶然发现了Quora上的这段代码.

#include<stdio.h>

main(){
          int           $[]
        ={0x69,       0154,107,
     'e',0x79,0157, 117,'v',0x6a}
     ,_,__;_=__^__;__=_;while(_<(-
      (~(1<<3))+3)){(_==1<<1||_==
       -(~(1<<3))||_==11)?putchar
        (*($+(1>>1))):putchar(*(
          __++ +$)),(_==1>>1||
            _==1<<2||_==(1<<3
              )-1)?putchar
                (' '):1;
                  _++;
                    }
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是i like you viji.它很动人,但很神秘.所以我用缩进格式化它以获得更好的主意.

main ()
{
  int $[] = { 0x69, 0154, 107,
    'e', 0x79, 0157, 117, 'v', 0x6a
  }
  , _, __;
  _ = __ ^ __;
  __ = _;
  while (_ < (-(~(1 << 3)) + 3))
    {
      (_ == 1 << 1 || _ ==
       -(~(1 << 3)) …
Run Code Online (Sandbox Code Playgroud)

c

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

对于无符号值的无符号字符类型,左值到右值转换的标准中特殊语言的意义何在

在C++ 14标准(n3797)中,左值转换的左值部分如下所示(强调我的):

4.1左值 - 右值 - 转换[conv.lval]

  1. T可以将非函数非数组类型的glvalue(3.10)转换为prvalue.如果T是不完整类型,则需要进行此转换的程序格式不正确.如果T是非类类型,则prvalue的类型是cv-nonqualified version T.否则prvalue的类型是T.

  2. 当在未评估的操作数或其子表达式中发生左值到右值转换时(第5条),不访问引用对象中包含的值.在所有其他情况下,转换结果根据以下规则确定:

    • 如果T是(可能是cv限定的)std::nullptr_t则结果是空指针常量.
    • 否则,如果T有类类型,则转换复制 - T从glvalue 初始化一个临时类型,转换的结果是临时的prvalue.
    • 否则,如果glvalue引用的对象包含无效指针值,则行为是实现定义的.
    • 否则,如果T是(可能是cv限定的)无符号字符类型,并且glvalue引用的对象包含不确定的值,并且该对象没有自动存储持续时间,或者glvalue是一元运算&符的操作数,或者它是绑定到引用,结果是一个未指定的值.
    • 否则,如果glvalue引用的对象具有不确定的值,则行为未定义.
    • 否则,glvalue指示的对象是prvalue结果.
  3. [ 注:另见3.10]

这一段有什么意义(粗体)?

如果此段落不在此处,那么它适用的情况将导致未定义的行为.通常,我希望unsigned char在具有不确定值时访问值会导致未定义的行为.但是,这一段意味着

  • 如果我实际上没有访问字符值,即我立即将其传递给&或将其绑定到引用,或者
  • 如果unsigned char没有自动存储时间,

然后转换产生一个未指定的值,而不是未定义的行为.

我是否正确地得出这个程序的结论:

#include <new>
#include <iostream>

// using T = int;
using T = unsigned char;

int main() {
  T * array = new T[500];
  for …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior language-lawyer lvalue-to-rvalue c++14

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

strlen是否具有未初始化值的字符串未定义行为?

strlen返回终止空字符前面的字符数.的实现strlen可能是这样的:

size_t strlen(const char * str)
{
    const char *s;
    for (s = str; *s; ++s) {}
    return(s - str);
}
Run Code Online (Sandbox Code Playgroud)

此特定实现取消引用s,其中s可能包含不确定的值.它相当于:

int a;
int* p = &a;
*p;
Run Code Online (Sandbox Code Playgroud)

因此,例如,如果有人这样做(导致strlen输出不正确):

char buffer[10];
buffer[9] = '\0';
strlen(buffer); 
Run Code Online (Sandbox Code Playgroud)

是不确定的行为?

c string strlen

6
推荐指数
1
解决办法
889
查看次数

由malloc()`分配的内存有哪些内容?

malloc()用于分配内存空间之后,我很好奇指针究竟是什么?该联机帮助页告诉我calloc()初始化已分配的内存空间为零.

malloc()函数分配大小字节并返回指向已分配内存的指针. 内存未初始化.如果size为0,则malloc()返回NULL或一个以后可以成功传递给free()的唯一指针值.

calloc()函数为每个大小为字节的nmemb元素数组分配内存,并返回指向已分配内存的指针. 内存设置为零.如果nmemb或size为0,则calloc()返回NULL或一个以后可以成功传递给free()的唯一指针值.

我在C中为C(haha)创建了一个非常简短的示例程序:

int main() {
    char *dynamic_chars;
    unsigned amount;
    printf("how much bytes you want to allocate?\n");
    scanf("%d", &amount);

    dynamic_chars = (char*)malloc(amount*sizeof(char));
    printf("allocated:\n%s\n", dynamic_chars);

    free(dynamic_chars);
    return 0;
Run Code Online (Sandbox Code Playgroud)

}

但是,在执行此代码时,它只输出任何内容.如果我初始化内存,例如0xFFFF使用循环初始化每个字节,那么程序会向我显示我期望的内容.内存空间实际存在,因为我不会收到错误声称我正在尝试访问未初始化的变量.

由于内存空间通常不会被删除但被标记为可重写,我想知道如果通过执行我的程序,我是否应该能够看到以前使用的随机内存字节?但我什么都看不到,所以我真的很困惑malloc().

EDIT1

关于malloc()或者可能是内存使用的另一件事,关于我的程序是有趣的:如果我使用calloc(),分配内存,我可以通过例如监视来跟踪我的程序的实际内存使用情况.例如,如果我告诉我的程序,每次分配1.000.000.000字节的内存calloc()我将在我的系统监视器中看到以下内容: 使用<code>malloc()</code>,我什么也看不见.我明白,只是通过分配内存,我当时并没有真正使用它,但我仍然感到困惑的是为什么我的操作系统(unix衍生物)不会将其识别为使用它.因为<code>malloc()</code>就像<code>calloc()</code>将物理地址返回到我没有得到的内存位置一样,这个内存区域似乎实际上并没有被操作系统保留.那么我可以在系统监视器中看到它吗?如果我想将此作为一个新问题发布,请告诉我.但我认为,因为问题仍然是关于<code>malloc()</code>它如何适应这里.</p> </div>
        <p>
          <a href=c malloc initialization dynamic-memory-allocation

5
推荐指数
1
解决办法
1814
查看次数

如何安全地实现"使用未初始化的内存来获取乐趣和利润"?

我想使用https://research.swtch.com/sparse中描述的技巧在C++中构建一个密集的整数集.这种方法通过允许自己读取未初始化的内存来实现良好的性能.

如何在不触发未定义行为的情况下实现此数据结构,并且不会与Valgrand或ASAN等工具发生冲突?

编辑:似乎响应者正在关注"未初始化"这个词,并在语言标准的上下文中对其进行解释.对我而言,这可能是一个糟糕的词语选择 - 这里"未初始化"仅意味着它的价值对于算法的正确运行并不重要.显然可以安全地实现这个数据结构(LLVM在SparseMultiSet中实现它).我的问题是,最好和最有效的方法是什么?

c++ valgrind data-structures

5
推荐指数
1
解决办法
384
查看次数

读取未初始化的值总是未定义的行为吗?或者有例外吗?

在读取值时,未定义行为(UB) 的一个明显示例是:

int a;
printf("%d\n", a);
Run Code Online (Sandbox Code Playgroud)

下面的例子呢?

int i = i;     // `i` is not initialized when we are reading it by assigning it to itself.
int x; x = x;  // Is this the same as above?
int y; int z = y;
Run Code Online (Sandbox Code Playgroud)

上面的三个例子都是 UB,还是有例外?

c

5
推荐指数
1
解决办法
252
查看次数