- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我有一个像矩阵或树这样的数据结构,并且我想从包含上述变量的非常大的函数中分解出 for 循环,那么调用应该是什么样子?我尝试了以下操作,但出现段错误。
void write_command(int w, char *argv[], char *string[]) {
char *dest;
for (int r = 0; argv[r] != NULL; r++) {
dest = malloc(sizeof(char *) * strlen(argv[r]) + 1);
*dest = '0';
strcpy(dest, argv[r]);
string[w][r] = *dest;
free(dest);
}
}
我想你明白我想要做什么,但是我应该如何声明变量?我在 string[w][r] = *dest;
处出现段错误。
我认为您不想看到我正在重构的内容,但它是有史以来最大且最难读的函数。
static int runCmd(const char *cmd) {
const char *cp;
pid_t pid;
int status;
struct command structcommand[15];
char **argv = 0;
int argc = 1;
bool pipe = false;
char *string[z][z];
char *pString3[40];
char *pString2[40];
int n = 0;
char **ptr1;
char string1[z];
bool keep = false;
char *pString1[z];
char *pString[z];
*pString1 = "\0";
*pString = "\0";
char *temp = {'\0'};
int w = 0;
bool b = false;
int j = 0;
int i;
int p = 0;
char **ptr;
char *tmpchar;
char *cmdtmp;
bool b1 = false;
char *dest;
int y = 0;
i = 0;
int h = 0;
nullterminate(string);
if (cmd) {
for (cp = cmd; *cp; cp++) {
if ((*cp >= 'a') && (*cp <= 'z')) {
continue;
}
if ((*cp >= 'A') && (*cp <= 'Z')) {
continue;
}
if (isDecimal(*cp)) {
continue;
}
if (isBlank(*cp)) {
continue;
}
if ((*cp == '.') || (*cp == '/') || (*cp == '-') ||
(*cp == '+') || (*cp == '=') || (*cp == '_') ||
(*cp == ':') || (*cp == ',') || (*cp == '\'') ||
(*cp == '"')) {
continue;
}
}
}
if (cmd) {
cmdtmp = malloc(sizeof(char *) * strlen(cmd) + 1);
strcpy(cmdtmp, cmd);
tmpchar = malloc(sizeof(char *) * strlen(cmd) + 1);
if (tmpchar == NULL) {
printf("Error allocating memory!\n"); /* print an error message */
return 1; /* return with failure */
}
strcpy(tmpchar, cmd);
ptr1 = str_split(pString3, cmdtmp, '|');
if (strstr(cmd, "|") == NULL) { /* not a pipeline */
makeArgs(cmd, &argc, (const char ***) &argv, pipe, 0, 0);
for (j = 0; j < argc; j++) {
string[0][j] = argv[j];
structcommand[i].argv = string[0]; /*process;*/
}
n++;
}
else {
for (i = 0; *(ptr1 + i); i++) { /* tokenize the input string for each pipeline*/
n++; /* save number of pipelines */
int e = 0; /* a counter */
*pString = "\0"; /* should malloc and free this? */
strcpy(string1, *(ptr1 + i));
if ((string1[0] != '\0') && !isspace(string1[0])) { /* this is neither the end nor a new argument */
ptr = str_split(pString2, *(&string1), ' '); /* split the string at the arguments */
h = 0;
for (j = 0; *(ptr + j); j++) { /* step through the arguments */
/* the pipeline is in cmdtmp and the argument/program is in ptr[i] */
if (ptr + j && !b && strstr(*(ptr + j), "'")) {
b = true;
strcpy(temp, *(ptr + j));
if (y < 1) {
y++;
}
}
while (b) {
if (*(ptr + j) && strstr(*(ptr + j), "'")) { /* end of quote */
b = false;
if (y < 1) {
string[i][j] = strcpy(temp, *(ptr + j));
}
y = 0;
}
else if (*(ptr + j)) { /* read until end of quote */
string[i][j] = temp;
continue;
} else {
b = false;
break;
}
}
if (ptr + j) {
if (*(ptr + j)[0] == '{') {
keep = true;
}
if (testFn(*(ptr + j))) { /* test for last char */
string[i][j - p] = concat(*pString1, *(ptr + j));
keep = false;
free(*pString1);
goto mylabel;
}
if (keep) {
*pString1 = concat(*pString1, *(ptr + j));
*pString1 = concat(*pString1, " ");
p++;
} else {
// strcpy(temp, *(ptr + j));
b1 = false;
int q = j;
for (e = 0; *(ptr + q + e); e++) { /* step through the string */
b1 = true;
if (*(ptr + e + q)) {
*pString = concat(*pString, *(ptr + e + q));
*pString = concat(*pString, " ");
}
j = e;
}
if (makeArgs(*pString, &argc, (const char ***) &argv, pipe, i, h)) {
write_command(&w, argv, string[w]);
/*for (int r = 0; argv[r] != NULL; r++) {
dest = malloc(sizeof(char *) * strlen(argv[r]) + 1);
*dest = '0';
strcpy(dest, argv[r]);
string[w][r] = dest;
}*/
w++;
} else {
if (!b1) { /* no args (?) */
for (int r = 0; argv[r] != NULL; r++) {
string[i][r] = argv[r];
}
}
}
}
}
}
mylabel:
free(ptr);
dump_argv((const char *) "d", argc, argv);
}
}
free(ptr1);
free(cmdtmp);
free(tmpchar);
}
for (i = 0; i < n; i++) {
for (j = 0; DEBUG && string[i][j] != NULL; j++) {
if (i == 0 && j == 0) printf("\n");
printf("p[%d][%d] %s\n", i, j, string[i][j]);
}
structcommand[i].argv = string[i];
}
fflush(NULL);
pid = fork();
if (pid < 0) {
perror("fork failed");
return -1;
}
/* If we are the child process, then go execute the string.*/
if (pid == 0) {
/* spawn(cmd);*/
fork_pipes(n, structcommand);
}
/*
* We are the parent process.
* Wait for the child to complete.
*/
status = 0;
while (((pid = waitpid(pid, &status, 0)) < 0) && (errno == EINTR));
if (pid < 0) {
fprintf(stderr, "Error from waitpid: %s", strerror(errno));
return -1;
}
if (WIFSIGNALED(status)) {
fprintf(stderr, "pid %ld: killed by signal %d\n",
(long) pid, WTERMSIG(status));
return -1;
}
}
return WEXITSTATUS(status);
}
最佳答案
我假设您正在尝试制作 argv
数组的深拷贝,这是一个以 NULL
结尾的字符串数组,例如C 程序的 main()
函数的第二个参数。您提供的函数似乎假设您已经为目标数组本身分配了空间;它的工作似乎仅限于复制参数字符串。
首先,然后:让我们看看调用者。如果您要制作标准参数 vector 的深拷贝,则目标变量的类型应与 argv 本身的类型兼容(通俗意义上的“兼容”)。如果副本的生命周期不需要延伸到宿主函数的返回之后,那么可变长度数组将是一个不错的选择:
char *copy[argc + 1];
这使您无需手动管理数组本身的内存,但无需管理唯一分配给其元素的任何内存。另一方面,如果您需要副本在声明它的函数返回后继续存在,那么您必须使用手动分配:
char **copy = malloc((argc + 1) * sizeof(*copy));
if (!copy) /* handle allocation failure */ ;
无论哪种方式,您都可以将结果数组或指针本身传递给 write_command()
函数,并且所需的参数类型是相同的。将指针传递给 copy 是没有意义的,因为该函数不会修改它作为参数接收的指针;相反,它会修改它指向的内存。
这是您想要的函数的签名:
void write_command(char *argv[], char *string[]) {
给定这样的签名,您可以将其称为...
write_command(argv, copy);
...
您似乎想要在内部循环中执行的关键步骤是
string[r] = strdup(argv[r]);
您可以使用 malloc()
、initialize、strcpy()
序列完成同样的事情,但是当 stdrup()
时,这有点愚蠢code> 已为同一任务做好了准备。但是,不要忘记检查其返回值(或者在原始代码中,malloc()
的返回值),以防内存分配失败。无论如何,您都不能释放 write_command()
中分配的内存,因为这会在复制的数组中留下无效的指针。
此外,即使调用者中确实有一个 char *
的二维数组,例如...
char *copies[n][argc + 1];
...函数write_command()
没有任何变化。它不需要知道或关心它复制到的数组是否是二维数组的元素。您只需适本地调用它,例如:
write_command(argv, copies[w]);
<小时/>
无论如何,您必须确保释放复制的参数字符串,但前提是您不再需要它们。同样,您不能在 write_command()
函数内执行此操作。
关于c - 如何选择函数原型(prototype)的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36958740/
以下代码,我使用 chrome 浏览器控制台进行了检查: function A(){ this.a='a' } 这是一个构造函数。我已经将一个属性 b 赋给了 A 的原型(prototype)。
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 5年前关闭。 Improve this
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 3年前关闭。 Improve this
我已经开始阅读 The Pragmatic Programmer,我很喜欢并学习堆形式,但我很难理解示踪子弹和原型(prototype)之间的区别。跟踪项目符号是否像拥有应用程序的所有 View 但尚
尽管阅读了 StackOverflow 上的大多数文章,但我现在实际上对原型(prototype)非常困惑。 function Foo() { } Foo.prototype.speak = func
我正在阅读以下代码,并开始想知道 Rectangle.prototype = Object.create(Shape.prototype) 和 Rectangle.prototype = Shape.
我想知道它们之间的区别: childObj.prototype = Object.create(parentObj.prototype) 和 childObj.prototype = parentOb
这个问题在这里已经有了答案: Why wouldn't I use Child.prototype = Parent.Prototype rather than Child.prototype =
在 node.js 中导出原型(prototype)的首选方法是什么?您可以采用两种方法: 导出原型(prototype)本身 function A () { } module.exports = A
我正在学习 JavaScript,发现了两种分配原型(prototype)的方法。 第一个是A.prototype = B.prototype,第二个是A.prototype = new B() 例如
在一些构造函数的定义之后,例如 child ,我见过以下两种形式: Child.prototype = Parent.prototype; 或 Child.prototype = new Parent
我正在阅读一本关于 OOP javascript 的书,但被其中一个示例卡住了。 在示例代码的第一个版本中,Shape 的一个新实例构造函数被创建并且 toString方法被调用。 toString方
这个问题在这里已经有了答案: What should I connect to the child prototype property in JavaScript (2 个答案) 关闭 8 年前。
在进行原型(prototype)设计时,您在多大程度上放弃了最佳实践来支持代码和修复黑客攻击?当然,代码并不打算在完整的生产环境中保留。 补充:我正在研究一个用 Python 制作的相当大的半工作原型
我正在尝试使用 Prototype 更新隐藏表单字段的值。表单域: 我正在尝试使用原型(prototype)更新值: var additionalVal = ',2'; var itemId = $
我正在阅读How to Make a Javascript Library我发现了作者所说的一个观点: function _() { //Some obects and var
我想用一个新函数扩展“Number”类型,因此我必须定义一个原型(prototype)。当我想到这一点时,我得到了一堆问题: Number 是否既继承了 Object.prototype 又继承了 F
这里好像有区别... 假设我们有 function MyConstructor() {} MyConstructor 的[[Prototype]] 是Function.prototype,不是 MyC
有人建议 Derived.prototype = Object.create(Base.prototype); 优于 Derived.prototype = new Base(); (如 this S
我是一名优秀的程序员,十分优秀!