- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在将字符串从命令行上的输入字符串复制到二维数组中的字符串时遇到问题。我的程序必须将由字母组成的字符串与任何非字母字符分开。例如 hello23ght.!good 需要放入二维数组中:
我已经找到了最长的字符串和字符串的数量,以便我可以为我的二维数组分配内存,如下所示。
char **stringArr; //array to hold seperated strings
stringArr = (char **)malloc(numOfStrings * sizeof(char*)); //malloc rows of 2d array
if(stringArr == NULL) { //checks to see if memory was allocated correctly
return 1;
}
int y;
for (y = 0; y < numOfStrings; y++) { //malloc columns of array
stringArr[y] = (char*) malloc((longestString + 1) * sizeof(char));
if(stringArr[y] == NULL) { //checks to see if memory was allocted correctly
return 1;
}
}
后记我编写了这段代码来查找输入字符串中的各个字母字符串,并将每个字母字符串放入二维数组的一个“槽”中:
while (argv[1][a] != '\0') { // Keep traversing the argument until the null char is reached
if (isAlpha(argv[1][a]) == 1) { // if the first char in argv[1] is a letter, copy it into the first row and first column of stringArr
stringArr[b][c] = argv[1][a];
printf("%c" , stringArr[b][c]); //test
a++;
c++;
//printf("%d %d \n", a, c);
} else if (a > 0 && isAlpha(argv[1][a]) != 1 && isAlpha(argv[1][a-1]) == 0) { //If the previous character is a letter and the current character isn't a letter increment a and b. (We have hit the end of the first unique string)
a++;
stringArr[b][c+1] = '\0'; //Setting the null byte for the unique string
b++; //incrementing b to the next unique string
printf("%d %d %d \n", a, b, c);
c = 0; // resetting c for the next unique string
} else {// if neither of the first two statments occur only increment var a since we have hit a repeating separating character.
a++;
}
}
但是,当我运行代码时,出现以下错误:
==46957==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ef37 at pc 0x000103a76b8c bp 0x7fff5c18a910 sp 0x7fff5c18a908
WRITE of size 1 at 0x60200000ef37 thread T0
SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 main
Shadow bytes around the buggy address:
0x1c0400001d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 07 fa
=>0x1c0400001de0: fa fa 07 fa fa fa[07]fa fa fa 00 06 fa fa 00 00
0x1c0400001df0: fa fa 00 04 fa fa 00 06 fa fa fd fd fa fa fd fd
0x1c0400001e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400001e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==46957==ABORTING
hlowrdjAbort trap: 6
我不确定到底出了什么问题,但我假设要么我没有为二维数组分配足够的内存,要么我的 while 语句没有准确地从输入字符串中复制唯一的字母字符串。
编辑我忘了添加这个,但 a、b 和 c 确实初始化为 0。
编辑2以下是如何检索 numOfStrings 和longestString
int j;
int numOfStrings=0, longestString=0, x=0;
//numOfStrings indicates total separated strings, longestString is the longest seperated string, x is the current length of the string
for (j = 0; argv[1][j] != '\0'; j++) { // Traversing through the input string
if (isAlpha(argv[1][j])) { //If the current char is a letter x is incremented by 1
x++;
} else if (!isAlpha(argv[1][j]) && isAlpha(argv[1][j-1])) { //If the current char is not a letter and the previous char is a letter then increment numberOfStrings by 1
numOfStrings++;
if (x > longestString) { //Since we hit a non letter char, if the x val is greater than the current longest string, replace longestString with x.
longestString = x;
}
x = 0;
}
}
if(isAlpha(argv[1][j - 1])) { //Checks the last character if it is a letter and then accounts for the string associated with that letter.
numOfStrings++;
if(x > longestString) { // If the last string is a the largest string then this will store its length in longestString
longestString = x;
}
}
编辑3我的 isAlpha 函数
int isAlpha (char a){
if ((65 <= a && a <= 90) || (97 <= a && a <= 122) ) {
return 1;
}
return 0;
} //Determines if a char is a letter or not using ASCII values. Returns 1 if true otherwise returns 0.
最佳答案
不知道如何计算numOfStrings
和longestString
,以及知道如何初始化运行索引 a
、b
、c
后,很难知道错误在哪里:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char **stringArr;
// emulating your allocation
stringArr = calloc(5, sizeof(char*));
stringArr[0] = calloc(1, 100);
stringArr[1] = calloc(1, 100);
stringArr[2] = calloc(1, 100);
stringArr[3] = calloc(1, 100);
stringArr[4] = calloc(1, 100);
if(argc != 2)
{
fprintf(stderr, "usage: %s arg\n", argv[0]);
return 1;
}
int i = 0; // index for scanning argv
int j = 0; // index of current stringArg buffer
int k = 0; // index of (end of) string in stringArg[j]
// state 0: alpha mode
// state 1: non-alpha mode
int state = 0;
char c;
while((c = argv[1][i++]))
{
if(isalpha(c))
{
if(state)
{
// previous character was a non-alpha
// change state and reset indices
state = 0;
k = 0;
j++;
}
stringArr[j][k] = c;
stringArr[j][++k] = 0;
continue;
}
// not alpha, ignoring
state = 1;
// if line starts with non-alpha
if(j == 0 && i == 1)
j--;
}
for(i = 0; stringArr[i][0]; ++i)
puts(stringArr[i]);
free(stringArr[0]);
free(stringArr[1]);
free(stringArr[2]);
free(stringArr[3]);
free(stringArr[4]);
free(stringArr);
return 0;
}
我决定将扫描状态存储在变量中。这使得较小的 if
条件,更容易阅读。我的版本也可以处理这种情况当该行以非字母字符开头时。
输出为:
$ valgrind ./a 'hello23ght.!good'
==20478== Memcheck, a memory error detector
==20478== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==20478== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==20478== Command: ./a hello23ght.!good
==20478==
hello
ght
good
==20478==
==20478== HEAP SUMMARY:
==20478== in use at exit: 0 bytes in 0 blocks
==20478== total heap usage: 7 allocs, 7 frees, 1,564 bytes allocated
==20478==
==20478== All heap blocks were freed -- no leaks are possible
==20478==
==20478== For counts of detected and suppressed errors, rerun with: -v
==20478== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
编辑
我认为我的猜测是正确的,您的运行索引的初始化a
,b
和 c
或计算 numOfStrings
和 longestString
的方式可能是问题所在。我认为您计算 numOfStrings
和 longestString
的方式可能是错误的。但如果没有代码,就很难判断。
我在程序中用你的循环替换了我的 while
循环,我删除了 printf
在此之前,我将运行索引 a
、b
、c
初始化为 0。我没有改变内存分配的模拟,所以我知道有该示例有足够的空间。
这是您的代码的结果:
$ valgrind ./a-ops-version 'hello23ght.!good'
==20877== Memcheck, a memory error detector
==20877== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==20877== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==20877== Command: ./a hello23ght.!good
==20877==
hello
ght
good
==20877==
==20877== HEAP SUMMARY:
==20877== in use at exit: 0 bytes in 0 blocks
==20877== total heap usage: 7 allocs, 7 frees, 1,564 bytes allocated
==20877==
==20877== All heap blocks were freed -- no leaks are possible
==20877==
==20877== For counts of detected and suppressed errors, rerun with: -v
==20877== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
编辑2
我在您的代码中发现了错误:
stringArr[b][c+1] = '\0';
当 b
索引最长字符串时,这会导致错误。当这条线是执行后,这意味着当前字符不是字母字符,所以在在上一个循环中,您已经将 c
增加了 1。这就是为什么当你阅读时非 alpha,c
已经是 '\0'
终止字节的索引,因此对于您超出范围写入的最长字符串。
为了说明这一点
'?'
是未初始化的字符
input: hello23ght.!good
Up until b == 0, a == 4, c == 4
hello23ght.!good
^
|
a
c
|
v
0 1 2 3 4 5
+---+---+---+---+---+---+
stringArr[b]: | h | e | l | l | o | ? |
+---+---+---+---+---+---+
这是结果
if (isAlpha(argv[1][a]) == 1) {
stringArr[b][c] = argv[1][a];
那你就这样做
a++;
c++;
因此,a
更新为 5,并读取下一个字符:
input: hello23ght.!good
Up until b == 0, a == 5, c == 5
hello23ght.!good
^
|
a
c
|
v
0 1 2 3 4 5
+---+---+---+---+---+---+
stringArr[b]: | h | e | l | l | o | ? |
+---+---+---+---+---+---+
因为 '2'
是非 alpha,所以执行 else
block
} else {
a++;
}
再次增加a
,现在是 6。
循环继续,else if
被评估为 true,因为最后一个字符也是非 Alpha:
stringArr[b][c+1] = '\0';
已执行,但你的写入超出了限制,因为numOfStrings
是 5:
input: hello23ght.!good
Up until b == 0, a == 6, c == 5
hello23ght.!good
^
|
a
c c+1
| |
v v
0 1 2 3 4 5 6
+---+---+---+---+---+---+
stringArr[b]: | h | e | l | l | o | ? | beyond the bounds
+---+---+---+---+---+---+
yields:
==22229== Invalid write of size 1
==22229== at 0x108C0E: main (a.c:93)
==22229== Address 0x51e64e6 is 0 bytes after a block of size 6 alloc'd
==22229== at 0x4C2CF05: calloc (vg_replace_malloc.c:711)
==22229== by 0x108A4B: main (a.c:62)
==22229==
要修复此问题,您必须删除 +1
:
stringArr[b][c] = '\0';
请注意,当且仅当非 Alpha 出现时,您的算法才会起作用对,你有这个输入hello234ght.!good
,那么你将编程由于第一个else if
而崩溃,您将增加b
,最终您超出了双指针的范围。
看看我的版本,在我的版本中,您可以拥有尽可能多的非阿尔法喜欢。
我鼓励您学习和使用调试器。此类错误很容易出现单步执行循环时的位置,因为使用调试器您可以看到这些值每一步的所有索引。
最后一个较小的批评:
在你的 isAlpha
中你有:
if ((65 <= a && a <= 90) || (97 <= a && a <= 122) )
这并没有错,但我认为这样做是一种不好的做法,数字看起来像神奇的数字,比如你是从哪里想出这个数字的?我知道这些是 a-z 和 A-Z 的 ASCII 代码。
这是一个更好的做法
if (('A' <= a && a <= 'Z') || ('a' <= a && a <= 'z') )
关于arrays - 发生堆缓冲区溢出不确定是否在 C 中正确为二维数组分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48470986/
这个问题在这里已经有了答案: Possible to make an event handler wait until async / Promise-based code is done? (2
我经常有多个运行的进程(R,Python,eshell/shell),对于每个进程,我经常都有一个相关的脚本,可以从中发送摘要。为此,我通常将每个框架垂直地分成两个窗口,以便脚本文件(例如.py)位于
如何修改 emacs 在关闭缓冲区后选择要显示的缓冲区的方式? 当我有多个列显示相同的缓冲区,然后在其中一个缓冲区中打开另一个文件,然后关闭新打开的缓冲区时,它不会切换回前一个缓冲区,而是切换到另一个
如何将 ex 命令复制到剪贴板或粘贴到缓冲区? 在 Windows 上使用 gvim。 最佳答案 windows剪贴板可以通过the buffer + 访问.因此,可以使用 + 将剪贴板粘贴为前命令。
在 javascript 中如何以比以下更简单的方式获取 b 缓冲区? var num=6553599 var a = new Buffer(4); a.writeInt32LE(num)
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
我有java考试,当我学习时,我看到了这个练习,我尝试解决它,但我发现一些困难,所以请帮助我考虑实用程序中方法的以下注释、 header 和部分代码名为 Atbash 的加密类。 /**
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
对于每个属性使用跨步顶点缓冲区与紧密打包缓冲区有何优缺点?我的意思是例如: 步幅:xyzrgb xyzrgb xyzrgb 紧:xyzxyzxyz rgbrgbrgb 乍一看,使用步幅时您似乎可以轻松
我正在尝试将文本文件中每行的数字读取到 ArrayList 中。当我执行以下函数时,它总是跳过最后一个元素。有人可以帮我吗?因为我在这里没有遇到问题,因为它读取直到缓冲区为空,所以他应该在到达 Fil
#include #include int main () { time_t time_raw_format; struct tm * ptr_time; char *buff
基本上我有一个包含不同类型数据的自定义结构。例如: typedef struct example_structure{ uint8_t* example_1[4]; int example_2[4];
我之前的列表实现是一个简单的 LinearLayout,位于一个装满我的项目的 ScrollView 中。 我切换到 ListView 的 Android 实现以简单地使用 CursorAdapter
我想创建一个可变长度的输入事件窗口/缓冲区,当它接收到额外的事件时会变长。 这是为了实现“键入时搜索”功能。我想捕获点击,但为了不给服务器造成压力,我想明智地进行服务调用。 我想到的逻辑是缓冲击键,从
我想将 yuv420P 像素写入缓冲区而不是二进制文件。假设我在指针中存储了 luma 、 Cb 和 Cr。 luma = output_pixel.luma; cb = output_pixel.c
我想在 Go 中构建一个支持多个并发读取器和一个写入器的缓冲区。所有写入缓冲区的内容都应由所有读者读取。允许新读者随时加入,这意味着已经写入的数据必须能够为迟到的读者回放。 缓冲区应满足以下接口(in
本文转载自微信公众号「小明菜市场」,作者小明菜市场。转载本文请联系小明菜市场公众号。 前言 Java NIO 需要理解的主要有缓冲区,通道,选择器,这三个主要的部分。 基础
一 点睛 NIO,可以称为 New IO 或 Non Blocking IO,是在 JDK 1.4 后提供的新 API。传统的I/O 是阻塞式的 I/O、面向流的操作;而 NIO 是非阻塞 I/O 、
我正在寻找一种切换到包含搜索文本的缓冲区的方法。 例如。如果我打开了 100 个缓冲区,我想切换到一个包含 'fooBar = 1' 的缓冲区 最佳答案 我写了一个 Vim 插件来做到这一点:buff
我正在尝试将提取的视频帧(我使用 ffmpeg)推送到 FFMPEG 缓冲区中。我已经查看了 ffmpeg 的缓冲区源文件,例如 buffersrc.c 和 fifo.c,以确定我是否可以这样做,但我
我是一名优秀的程序员,十分优秀!