我正在尝试实现一个C函数char * strShiftLeft(char * string,int n),它接受字符串(str)和一个int n,表示str左移多少个字符。例如,如果我们将其称为strShiftLeft(《托马斯》,2),当我们追加前2个字符时,函数应该返回一个字符指针,指向字符串"omasTh(n)个字符到字符串的末尾,并且每字符向左移位2个时隙。
然而,由于某种原因,当我编译我的程序时,它编译得很好,但当我在Mac上运行它时,我的终端一直显示:
zsh: bus error ./a.out
下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
char* strShiftLeft(char* str, int n)
{
// If the passed in string is NULL, return NULL
if (str == NULL)
{
printf("NULL!\n");
return NULL;
}
// Get the length of the string
int len = 0;
char* counter_ptr = str;
while (*counter_ptr != '\0')
{
len++;
counter_ptr++;
}
printf("len: %d\n", len);
// If the integer is longer than the string, return back NULL
if (n > len)
{
printf("n too big!\n");
return NULL;
}
// Create a temp char array to store 1st n chars to append to the end of string later
char temp_arr[n];
for (int i = 0; i < n; i++)
{
*(temp_arr + i) = *(str + i);
}
printf("temp_arr = %s\n", temp_arr);
printf("str is still: %s\n", str);
// So far so good
char* temp = str + n;
printf("len - n = %d\n", len - n);
// Update first (len - n) characters of the string (e.g. n = 2, "Thomas" -> "omasas")
for (int i = 0; i < (len - n); i++)
{
printf("*temp = %c\n", *temp);
printf("*(temp - n) = %c\n", *(temp - n));
*(temp - n) = *(temp); // THIS LINE SEEMS TO BE THE ONE CAUSING ERRORS
temp++;
}
temp = str + (len - n);
for (int i = 0; i < n; i++)
{
*(temp + i) = *(temp_arr+i); // THIS LINE ALSO SEEMS TO BE CAUSING ERRORS
}
return str;
}
int main()
{
char* str = strShiftLeft("Thomas", 2);
printf("%s\n", str); // Should print out "omasTh"
return 0;
}
我用了很多printf()来找出问题所在。我注意到有两行代码似乎导致了一些错误,即:(一)
*(temp - n) = *(temp);
*(temp + i) = *(temp_arr+i);
我想用这两行代码做的是,用字符串中其他元素的值来更新字符串中某些元素的值。
虽然我的代码编译了,但当我运行它时,它显示"zsh:bus error ./a. out "。我试着使用一些在线编译器。当我运行我的代码时,我得到了seg错误。
我不知道我犯了什么错。
如果有人能帮我找出我所犯的错误,我将不胜感激。
注意,我不允许使用动态内存分配,括号操作符来解引用指针,或者任何来自C库的函数,比如strlen(),strcpy()等等。谢谢!
我已经使用printf()来查明哪些行导致错误,但是我不明白为什么它们会导致错误。
1条答案
按热度按时间fxnxkyjh1#
当调用
strShiftLeft("Thomas", 2);
时,向strShiftLeft()
传递的是字符串文字的地址。strShiftLeft()
然后继续尝试并就地修改您传递给它的字符串,这意味着它尝试修改字符串文字。在C中修改字符串字面量是“未定义的行为”,这意味着任何事情都可能发生。
***任何内容***包括:
然而,这并不是您的情况,因为您没有收到segfault,而是收到了总线错误,总线错误意味着您的程序不仅仅试图写入只读存储器;这意味着它试图寻址甚至不能被寻址的存储器。
导致总线错误的原因很可能是:
发生的情况是,您忘记了以null终止
temp_arr
,因此printf()
函数打印temp_arr
包含的任何内容,然后在temp_arr
结束后继续打印。由于temp_arr
位于堆栈中,printf()
尝试从内存读取堆栈结束后的内容,这很可能是一些无效页。这是开始使用调试器并停止使用
printf()
语句的另一个原因。