相关疑难解决方法(0)

访问绑定的未定义行为之外的全局数组?

我今天刚上课了 - 阅读C代码和输入,如果程序实际运行,所需答案就是屏幕上显示的内容.其中一个问题被声明a[4][4]为一个全局变量,并且在该程序的一个点上,它试图访问a[27][27],所以我回答了类似" 访问一个超出其边界的数组是一个未定义的行为 ",但老师说它a[27][27]的值将为0.

之后,我尝试了一些代码来检查"所有未初始化的golbal变量是否设置为0"是否为真.好吧,这似乎是真的.

所以现在我的问题是:

  • 似乎已经清除了一些额外的内存并保留了代码运行.保留多少内存?为什么编译器会保留比应该更多的内存,它的用途是什么?
  • a[27][27]0所有环境?

编辑:

在该代码中,a[4][4]唯一声明的全局变量,并且还有一些更多本地变量main().

我在DevC++中再次尝试了该代码.所有这些都是0.但在VSE中并非如此,其中大多数值都是,0但有些值具有Vyktor指出的随机值.

c undefined-behavior

60
推荐指数
7
解决办法
3235
查看次数

数组索引在C中超出范围

为什么C在数组索引超出限制的情况下进行区分

#include <stdio.h>
int main()
{
    int a[10];
    a[3]=4;
    a[11]=3;//does not give segmentation fault
    a[25]=4;//does not give segmentation fault
    a[20000]=3; //gives segmentation fault
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,它正在尝试访问分配给进程或线程的内存,如果是a[11]或者a[25]它正在超出堆栈边界a[20000].

为什么编译器或链接器没有出错,他们不知道数组大小?如果没有,那么如何sizeof(a)正常工作?

c c++ arrays

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

没有出界错误

我在C中有这个代码,它接受了一堆chars

#include<stdio.h> 
# define NEWLINE '\n'
int main()
{

char c;
char str[6];
int i = 0;
while( ((c = getchar()) != NEWLINE))
{
        str[i] = c;
        ++i;
        printf("%d\n", i);
}

return 0;
}
Run Code Online (Sandbox Code Playgroud)

输入是:testtesttest

输出:1 2 3 4 5 6 7 8 117 118 119 120

我的问题是:

  1. 虽然我明显超出了阵列的容量,为什么我不会出现超出界限(分段错误)的异常?

  2. 为什么输出中的数字会突然跳到很大的数字?

我在C++中试过这个并且得到了相同的行为.请问有谁可以解释一下这是什么原因?

c indexoutofboundsexception

12
推荐指数
2
解决办法
2万
查看次数

C/C++故意超出范围索引

说我有一个像这样的数组:

int val[10];
Run Code Online (Sandbox Code Playgroud)

我故意用从负值到任何高于9的值来索引它,但没有以任何方式使用结果值.这可能是出于性能原因(也许在进行数组访问后检查输入索引会更有效).

我的问题是:

  1. 这样做是否安全,或者我是否会遇到某种内存保护障碍,有可能破坏某些指数的内存或类似情况?
  2. 如果我像这样访问超出范围的数据,它可能没有效率吗?(假设数组没有内置范围检查).
  3. 这会被认为是不好的做法吗?(假设写了一条注释,表示我们知道使用超出范围的索引).

c c++ arrays

6
推荐指数
3
解决办法
466
查看次数

矢量化的strlen逃脱阅读未分配的记忆

在研究OSX 10.9.4的strlen实现时,我注意到它总是比较一个16字节的块并向前跳过到接下来的16个字节,直到它遇到'\0''.相关部分:

3de0:   48 83 c7 10             add    $0x10,%rdi
3de4:   66 0f ef c0             pxor   %xmm0,%xmm0
3de8:   66 0f 74 07             pcmpeqb (%rdi),%xmm0
3dec:   66 0f d7 f0             pmovmskb %xmm0,%esi
3df0:   85 f6                   test   %esi,%esi
3df2:   74 ec                   je     3de0 <__platform_strlen+0x40>
Run Code Online (Sandbox Code Playgroud)

0x10 十六进制是16个字节.

当我看到它时,我想知道:这个记忆也可以不被分配.如果我已经分配了一个20字节的C字符串并将其传递给strlen它,它将读取36字节的内存.为什么允许这样做?我开始寻找并发现访问数组越界有多危险?

例如,这证实了它绝对不是一件好事,未分配的内存可能未被映射.然而,必须有一些东西使这项工作.我的一些假设:

  • OSX不仅保证其分配是16字节对齐的,而且还保证分配的"量子"是16字节的块.换句话说,分配5个字节实际上将分配16个字节.分配20个字节实际上将分配32个字节.
  • 当你编写asm时读取数组的结尾本身并没有坏处,因为它不是未定义的行为,只要它在界限内(在页面内?).

究竟是什么原因?

编辑:刚刚找到为什么我获得了未分配内存的读写权限?,这似乎表明我的第一个猜测是正确的.

编辑2:愚蠢的是,我已经忘记了尽管Apple似乎已经删除了大多数asm实现的源代码(OSX的x86-64汇编libc例程在哪里?),但是它留下了strlen:http://www.opensource .apple.com /源极/ libc的/ libc的-997.90.3/x86_64的/串/ strlen.s

在评论中我们发现:

//  returns the length of the string s (i.e. the …
Run Code Online (Sandbox Code Playgroud)

c macos assembly memory-management libc

6
推荐指数
2
解决办法
461
查看次数

为什么可变长度数组在这个C代码中工作?

#include "stdio.h"

int main()
    {
        int n;
        printf("Enter n:\n");
        scanf("%d",&n);

        int arr[n][n];
        arr[3][3] = 4;
        printf("%d",arr[3][3]);
        getchar();
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

没有使用int arr[n],其中n是变量,在C中是非法的?我想知道这里发生了什么.显然,代码适用于我clang LLVM compilerIDEOne以及Codeblocks.我想编译器只是通过自动内存分配让事情变得简单.但另一个惊人的事实是,当我尝试设置n为1,2或3时,它仍然有效.

c arrays

4
推荐指数
1
解决办法
108
查看次数

为什么gcc打印"Segmentation fault:11"?

当我使用gcc编译器在程序下面运行时,我最终出现在"Segmentation fault:11"中,但是当我在" https://www.onlinegdb.com/online_c_compiler "运行时,它执行得非常好.我想知道,为什么gcc在这里抛出分段错误?

#include <stdio.h>

int main(){

    typedef int myArray[10];

    myArray x = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};//Equivalant to x[10]
    myArray y[2]; //equivalant to y[10][2]

    int counter = 0;

    for(int i = 0; i < 10; i++){
        for(int j = 0; j < 2; j++){
            //printf("%i %i\n", i, j);
            y[i][j] = counter++;
        }
    }

    printf("\n\nElements in array x are\n");
    for(int i = 0; i < 10; i++){
        printf("x[%i] = %i\n", i, x[i]);
    }

    printf("\n\nElements …
Run Code Online (Sandbox Code Playgroud)

c gcc

3
推荐指数
1
解决办法
86
查看次数

这是传输结束符还是其他?

所以我正在用标准C做一个字符串基础教程。

我有:

char mystring[] = "HAL";
for (int i = 0; i < 3; i++) 
    mystring[i] += 1;
for (int k = 0; k < 10; k++)
    printf("\n %d", mystring[k]);
Run Code Online (Sandbox Code Playgroud)

输出:

73
66
77
0
4
0
0
0
0
0
Run Code Online (Sandbox Code Playgroud)

现在mystring [3] = 0对我来说很有意义,因为我读到字符串文字以空字符结尾,因此字节数为n + 1个字符。我不知道为什么mystring [4] = 4。我在一个ascii表中查了4个,说它是“传输结束”。我在C字符串的传输字符末尾做了一些Google快速搜索,但没有找到任何东西。所以有人可以告诉我这是怎么回事吗?这是标准的东西吗?我什么时候可以期待它发生?

c arrays ascii

2
推荐指数
1
解决办法
597
查看次数

删除数组只会偶尔失败

我正在学习C++指针,遇到了一个非常奇怪的问题.我们的任务是push_back为我们自己的类编写自己的函数,该类包含一个整数数组.

我有以下简单的功能:

void IntRow::push_back(int value){
    int *elements_temp = new int[size+1];
    for (int i = 0; i <= size; i++){
        elements_temp[i] = elements[i];
    }
    elements_temp[size + 1] = value;
    elements = new int[size+1];
    for (int i = 0; i <= size+1; i++){
        elements[i] = elements_temp[i];
    }
    delete [] elements_temp;
    size++;
}
Run Code Online (Sandbox Code Playgroud)

然而,这失败了,但仅有一些在线:delete [] elements_temp;

出现以下错误消息:

incorrect checksum for freed object - object was probably modified after being freed.
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况,为什么有时会发生这种情况呢?

PS:elements_temp在功能存在之后,我实际上是否必须释放或者是否已释放?

c++ arrays pointers

2
推荐指数
1
解决办法
59
查看次数

argc/argv 随机数据/行为

这是我的最小可重现示例:

#include <stdio.h>

int main( int argc, char* argv[])
{
    printf (" this is the contents of argc:%d\n",argc);
            
    int i;

    for (i = 0; i < argc ; i++){
       printf(" argv = %d = %s\n",i,argv[i]);
    }
      
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我argc将 for 循环更改为数字时,比方说10,代码在到达之前崩溃10

$ ./argc one two three
 this is the contents of argc:4
 argv = 0 = ./argc
 argv = 1 = one
 argv = 2 = two
 argv = 3 = three
 argv …
Run Code Online (Sandbox Code Playgroud)

c argv argc

2
推荐指数
1
解决办法
159
查看次数